The build succeeded. It also warned that the firmware had almost no useful headroom.
That did not mean a device had failed. It meant a successful compile was hiding an unhealthy product: too little margin for the next fix, a dependency change or a safe recovery path.
For a software-first team, that message was wonderfully clarifying. On embedded hardware, every abstraction eventually becomes a physical resource decision.
A successful build is not a release criterion
Cloud software makes capacity feel elastic. A service can often receive more memory, more instances or a larger container. An embedded device has fixed resources inside the product.
Firmware must fit inside a layout that supports startup, configuration, storage and safe maintenance. Recovery depends on preserving enough space and keeping the supporting lifecycle logic intact.
When application code consumes nearly every byte, the team loses operational options. An urgent security fix or dependency patch may no longer fit, while a superficial capacity change can quietly weaken recovery or storage.
The correct response is not merely to silence the warning. It is to restore headroom and protect it as a release property.
Flash is only one budget
The device also has to manage memory at runtime.
Images, audio, secure networking, concurrent tasks and temporary payloads all compete for memory, often at the same moment.
Optimising one path can destabilise another. Increasing an audio buffer may reduce playback gaps but leave less memory for a page capture. Keeping a large image in memory while opening a secure connection may succeed most of the time and fail under fragmentation.
This is why the worst bugs can be intermittent. The code is valid. The components work. The combination fails only with a particular timing and allocation pattern.
Audio buffering is not free
The realtime voice path makes the trade-off visible.
Small playback chunks can begin quickly but are sensitive to network jitter and task scheduling. Large chunks can smooth playback while increasing the delay before the first word and consuming memory that other peripherals need.
Capture has similar tension. A long fixed window is easy to implement but feels slow and records unnecessary silence. Voice activity detection can end a turn earlier, but thresholds that work for an adult developer in a quiet office may miss a child speaking in a noisy room.
Every buffer therefore has at least three costs: memory, latency and failure behaviour.
Wi-Fi is part of the product surface
A prototype on strong office Wi-Fi can make the network disappear. A family home brings weak coverage, router restarts, captive portals, changing credentials and interference.
The firmware needs timeouts, reconnect behaviour and a clear path back to idle. A maintenance-service problem should not unnecessarily block the core experience, and an interrupted session should clean up rather than retain stale state.
None of this is glamorous, but it determines whether the product feels dependable. “The cloud is healthy” does not help the child sitting beside a silent device.
Battery and heat are architectural constraints
Wi-Fi, camera use and speaker output all draw power. A larger buffer may keep the processor active longer. An always-on microphone or camera would affect both battery life and privacy. High-volume audio changes runtime and thermal behaviour.
Then we place the electronics inside plush fabric and stuffing.
That enclosure is friendly to a child and unfriendly to heat dissipation. Charging decisions must consider cell protection, voltage conversion, accessible connectors, temperature and the behaviour of the product while charging. These are safety decisions that require qualified hardware and product-safety expertise.
The software can help by powering down peripherals, bounding sessions and returning to a low-power state. It cannot compensate for an unsafe electrical or mechanical design.
Manufacturing changes the acoustics
A working prototype is one data point. Production introduces tolerances.
A camera mount can shift. Fur can cover the lens. A microphone opening can be smaller than intended. Stuffing density can alter both the shape of the face and the way sound travels. A speaker that is clear on an exposed bench can become muffled inside the final enclosure.
Prototype testing showed how small variations in assembly can affect image and audio quality. The AI model may be unchanged while the product experience changes substantially.
This is why the complete enclosure has to be part of the test system.
Practices we now treat as non-negotiable
The first is an explicit firmware-size budget. Automated checks should report application size and fail before headroom becomes negligible. The threshold should protect future fixes and the recovery strategy, not merely current compilation.
The second is an invariant check for lifecycle and maintenance behaviour. The repository should verify that supported recovery paths remain present and correctly sequenced.
A useful release gate should show change from the previous release, remaining margin and the reason for any large increase. That turns size from a late warning into a reviewable engineering decision.
The third is representative device testing. Emulators and cloud tests are valuable, but they cannot reproduce speaker acoustics, camera alignment, heap fragmentation, battery behaviour or weak home Wi-Fi.
The fourth is measurement over intuition: free memory at key transitions, largest allocation blocks, page-image size, audio underruns, time to first audio, battery voltage and stop reasons.
Finally, recovery must be tested, not assumed. The maintenance path matters most when a new release is the thing that went wrong.
The physical cost of “one more feature”
Software teams often talk about technical debt as future maintenance effort. Hardware turns some of that debt into immediate inventory, battery, heat, memory and recovery risk.
A new library can change the storage budget. A longer session can change the battery target. A different camera setting can change transfer cost and memory. A louder voice can expose amplifier or enclosure limitations.
The lesson is not to avoid features. It is to price them in the resources the product actually has.
That warning was useful because it made an invisible assumption visible. The firmware did not merely need to work today. It needed enough room to remain fixable tomorrow.
Next in the series: the product decisions — teddy, book, eye, button and session boundaries — that mattered more than our model choice.
Tell Me Ted is an independent, pre-launch project that I work on outside my role at HubSpot. The views expressed here are my own and do not represent HubSpot.