A USB3 Vision camera that shows you what happened three seconds ago, while the configuration file asks for 60 fps, has two separate problems stacked on top of each other. The first is a Linux kernel limit on USB transfer memory that makes the driver reject frame submissions entirely. The second is physics: a fixed 100,000 µs exposure time caps the frame rate at roughly 10 fps before the camera even tries to go faster. This walkthrough separates the two, shows the arithmetic, and gives you the commands and settings to fix each one.
The symptom and what it tells you
The classic picture is a USB3 camera on a Linux PC, configured for 60 fps, that actually delivers a slow stream with seconds of latency: you walk past the lens at t = 6 s and appear on screen at t = 9 s. Two messages appear in the log:
Error: ... Not enough memory to submit transfer. You can increase the usbfs memory by modifying /sys/module/usbcore/parameters/usbfs_memory_mb.- A warning that the target brightness was not reached before a 5 s timeout, with the exposure stuck at 100000 µs.
Each message names one of the two root causes. Treat them independently: fixing only one leaves you with either a lagging stream or a slow one.
Cause 1: the usbfs memory limit
When a USB3 Vision driver captures, it does not pull each frame across the bus one at a time. It submits several frame-sized transfer requests to the kernel at once, so the camera can stream continuously while earlier frames are still being fetched. Each queued request reserves kernel memory from a pool called usbfs, and Linux caps that pool at 16 MB by default — a value chosen long before machine-vision cameras pushed hundreds of megabytes per second through USB3.
Do the arithmetic for a typical camera. A 12 MP mono frame at 8 bits per pixel is about 12 MB. Queueing even two such frames already exceeds the 16 MB default. The driver's submission fails, the grab errors out, frames pile up in the camera, and every image you eventually receive is old — that is where the multi-second latency comes from, not from slow image processing.
The fix is documented in every major USB3 Vision driver's performance notes: raise usbfs_memory_mb well above your queued transfer total.
Temporary fix (until reboot)
-
Check the current limit:
cat /sys/module/usbcore/parameters/usbfs_memory_mbIt usually prints
16. -
Raise it to 1000 MB:
sudo sh -c 'echo 1000 > /sys/module/usbcore/parameters/usbfs_memory_mb' -
Restart the camera stream and confirm the
Not enough memory to submit transfererrors are gone.
Permanent fix (survives reboot)
Add usbcore.usbfs_memory_mb=1000 to your kernel command line (in the GRUB configuration, on the line with GRUB_CMDLINE_LINUX_DEFAULT), then run sudo update-grub and reboot. Verify with the same cat command. For production machines, always use the permanent method — the sysfs write is for bench testing.
If transfer errors persist after the limit is raised, the problem has moved from memory to bandwidth or cabling — see USB3 Vision transfer errors: diagnose bandwidth and buffers for that stage of the diagnosis.
Cause 2: the exposure time caps the frame rate
Even with the buffer fixed, the configuration above still cannot reach 60 fps, because of one line: exposure: 100000.0 — a fixed 100,000 µs (0.1 s) exposure.
A camera cannot start the next exposure until the current one finishes and the sensor is read out. The frame period is therefore at least exposure plus readout:
Worked example with the numbers from the failing configuration:
- Exposure: 100,000 µs = 0.1 s
- Readout of a modest 10 ms = 0.01 s
- Minimum frame period: 0.1 + 0.01 = 0.11 s
- Maximum frame rate: 1 / 0.11 ≈ 9 fps
So the camera delivers about 9–10 fps no matter what frame rate the file requests. The frame-rate setting is a ceiling, not a generator of speed. To reach 60 fps, the exposure must fall to roughly 1/60 s ≈ 16 ms or less, minus readout. The same logic is explained from the camera side in RGB camera frame rate limits: pixel format and exposure.
The practical consequence: at 60 fps you have about 15 ms of light-gathering time per frame. If your images go dark, the answer is more light or a wider aperture, not a longer exposure.
Use the camera resolution calculator when you also need to check whether binning or an ROI change would reduce the frame size and raise the achievable rate.
The brightness-search timeout explained
The third symptom — Did not reach the target brightness before timeout with brightness stuck at a nonsense value like -1.77e+08 — follows from the same fixed exposure.
The driver was asked to reach a target brightness while the exposure was pinned at 100,000 µs. With exposure fixed, the only free parameter is gain, and the gain range is tiny compared with the exposure range. The search runs out of room, never converges, and reports failure. Remove the fixed exposure (or replace it with a sensible upper limit) whenever you enable auto brightness, so the search can actually move the parameter that matters. If saved startup settings keep overriding your limits, see Auto exposure upper limit not applied: check startup settings.
Test each cause in order
-
Confirm the buffer fix. Raise
usbfs_memory_mb, restart the stream, and check that the memory errors stop. Latency should drop from seconds to near zero. - Measure the real frame rate. Read the actual achieved rate from the driver or count message timestamps over 10 s. Expect roughly 10 fps with the 100,000 µs exposure still in place — that is correct behaviour, not a fault.
- Shorten the exposure. Remove the fixed value or set it to ~15,000 µs, add lighting if the image dims, and re-measure. The rate should climb toward the configured target.
- Re-run the brightness search. With exposure free to move, the target brightness should be reached within the timeout.
- If the rate is still short, the bottleneck has moved elsewhere — follow Camera not reaching max frame rate: find the bottleneck to separate camera, bus, driver and host limits.
Checks before you blame the camera
- The camera is on a dedicated USB3 port, not a hub shared with other devices.
- The cable is a machine-vision grade USB3 cable with screw locks, sized for the run — long passive cables degrade signal quality and cause transfer faults rather than memory errors.
- The host controller is a proper USB3 card, not an onboard port shared with the system's other peripherals.
For a multi-camera station, a quad USB3 adaptor gives each camera its own controller path:
- Interface
- USB3
- Ports
- 4 ports
A high-flex cable rated for drag-chain use survives moving-camera setups where standard cables work loose:
For a deeper treatment of how trigger mode interacts with the achievable frame rate, this guide to calculating camera frame rate in trigger modes works through the same period-versus-exposure arithmetic from the camera's side.
When the usual answer is wrong
-
More RAM does not help. The failing limit is a kernel parameter, not the 24 GB of system memory. A bigger PC changes nothing until
usbfs_memory_mbis raised. - Raising the configured frame rate does nothing while the exposure is 100,000 µs. The camera obeys the exposure, not the request.
- Removing the exposure setting can make the image dark at high frame rates, because each frame now gathers light for ~15 ms. Budget for brighter lighting before you shorten exposure.
- Latency is not processing lag. Three-second-old frames come from a stalled transfer queue, not from slow software. Fixing the queue removes the latency even with no code changes.
A short checklist
- Raise
usbfs_memory_mbto 1000 and confirm the memory error is gone. - Make the change permanent on production machines via the kernel command line.
- Compute the exposure ceiling: max fps ≈ 1 / (exposure + readout).
- Set exposure to at most ~1/target_fps, or leave it to auto with a sensible upper limit.
- Verify the achieved rate by measurement, not by the config file.
- Check cable, port and controller when errors rather than slowness remain.
Cameras and parts that fit this workflow
Any USB3 Vision camera benefits from the same two fixes. Two examples from our area scan cameras:
- Sensor format
- 1/1.8"
- Lens mount
- C-mount
- Interface
- USB3
- Resolution
- 6-10 MP
- Sensor format
- 1/1.7"
- Interface
- USB3
- Resolution
- 12 MP
- Shutter
- Rolling
Both pair with the USB3 adaptors and cables above through the accessories finder, or start from the system configurator if you are building the station from scratch.
If the symptoms change after these fixes — dropped frames instead of slow frames — move on to machine vision network congestion: diagnose transfer faults for the bus-level diagnosis. And if you would rather talk through the set-up with us, use the contact page: free expert support comes with every order.
Questions
What does the error 'Not enough memory to submit transfer' mean?
The Linux usbcore module limits the memory USB transfers may reserve, and the default is small: 16 MB. A USB3 Vision camera submitting several large uncompressed frames at once exceeds that limit, so the driver rejects the transfer and the grab fails. Raise the limit by writing a larger value, such as 1000, to /sys/module/usbcore/parameters/usbfs_memory_mb, or set usbcore.usbfs_memory_mb=1000 on the kernel command line to make it permanent.
Why does 100,000 µs exposure limit the frame rate to about 10 fps?
A camera can only start the next exposure after the current one finishes, so the frame period is at least the exposure time plus the sensor readout. With 100,000 µs (0.1 s) of exposure, the ceiling is 1 / 0.1 = 10 frames per second before readout overhead. The frame-rate setting in the configuration is a target, not a guarantee: the camera simply cannot deliver more frames than the exposure time permits. Shorten the exposure and add light so the image stays bright.
Is raising usbfs_memory_mb temporary or permanent?
Writing to /sys/module/usbcore/parameters/usbfs_memory_mb takes effect immediately but is lost at reboot. For a permanent change, add usbcore.usbfs_memory_mb=1000 to the kernel parameters (for example in the GRUB configuration) and reboot. For production machines, use the permanent method; for a quick bench test, the sysfs write is faster.
Why did the auto-brightness search time out at that exposure?
The camera was set to a fixed long exposure and asked to reach a target brightness. Because exposure was fixed, the search could only adjust gain, whose range is far narrower than the exposure range, so it never converged and timed out with an absurd brightness reading. Leave the exposure unset (or set only a sensible upper limit) when you ask for automatic brightness, so the search has room to work.
Could a bad cable or USB controller cause the same symptoms?
Yes, but with different signatures. A marginal cable or a hub sharing bandwidth usually shows up as transfer errors and dropped packets rather than a clean transfer-submission failure. Check that the camera is on a dedicated USB3 controller, use a short high-quality cable with locking screws in drag-chain applications, and watch the error counters to tell bandwidth problems from the memory-limit failure.



