Acknowledged
CIQQA-3313

Holistic Review of CIQ Limitations for Large Applications

I'm currently developing a Connect IQ application that seems to push against nearly all of the platform’s limitations.

The app is a client for openHAB, a widely-used open-source home automation platform. Users configure what they want to see and control on the Garmin device via the openHAB server—ranging from a few devices to fully integrated smart homes.

Through this work, I've encountered several areas where the Connect IQ platform presents challenges for more complex applications.

1. Network Request Limits (-402 Error)

My app can hit the -402 request limit. While this is handled fairly well by the API, the behavior is not well documented and differs between the simulator and real devices.

https://forums.garmin.com/developer/connect-iq/i/bug-reports/request-for-documentation-and-simulator-accuracy-on-makewebrequest-limits

2. Storage Limits

The documented storage limits appear inconsistent and do not reflect actual behavior. Storage.setValue() can store more data than expected, but this consumes significant memory—and if the memory limit is hit, the app crashes without warning. It’s difficult to guard against this.

https://forums.garmin.com/developer/connect-iq/i/bug-reports/storage-setvalue-should-handle-memory-limits-gracefully

3. Stack Size and Recursive Structures

When parsing complex or recursive JSON structures, I encounter stack overflows. While I’ve restructured parts of the code to use iterative processing, it comes with overhead. A modest increase in stack size—at least as an option—could be helpful for apps like mine.

https://forums.garmin.com/developer/connect-iq/i/bug-reports/proposal-allow-larger-stack-for-recursive-data-handling

4. Watchdog Limit Handling

The Watchdog limit is another frequent bottleneck. While I work around it using an asynchronous task queue, there's no visibility into the remaining execution budget. A system stat indicating remaining Watchdog time, along with a native task queue implementation in the SDK, would be extremely valuable.

https://forums.garmin.com/developer/connect-iq/i/bug-reports/suggestion-watchdog-budget-indicator-and-built-in-task-queue-support-in-sdk

5. Profiler Reliability

Accurate profiling is critical for performance tuning in larger apps, but the current profiler can mislabel or misreport entries—making it difficult to trust the results. I’ve encountered this personally, and others have reported similar issues.

Example issue: https://forums.garmin.com/developer/connect-iq/i/bug-reports/bug-profiler-inconsistency

6. Conclusion

As you can see, I’ve submitted several targeted suggestions and bug reports. The purpose of this post is to suggest looking at these issues more holistically.

It's completely understandable that wearables have limited resources compared to phones or tablets. But if CIQ is to support more capable and dynamic apps, then:

  • Limits should be clearly documented.

  • The SDK should provide tools and APIs that help developers handle these limits gracefully.

I'm not sure if supporting larger apps like mine aligns with Garmin’s vision for CIQ. But if it does, I believe there’s important work to be done to make that experience more robust and developer-friendly.

  • If you were to start a similar app today, don't you think it would be easier as you'd know the pitfalls and what to watch for?

    Yes and no. Yes, I'd have a better understanding of the pitfalls and what to expect. But no, it wouldn't necessarily be easier — because the real issue isn't just lack of experience. It's that the SDK and API simply don't provide the tools needed to address the problems I encountered. These aren't challenges you can "learn your way out of"; they require a more capable and robust API.

  • If you were to start a similar app today, don't you think it would be easier as you'd know the pitfalls and what to watch for?

    It's the "learning curve" in this environment.  And there is one..

    People have been doing complex/large CIQ apps for a decade (including me) and I'll tell you, some of the apps I wrote early on would be done differently today.  In fact, in a couple cases I basically re-wrote the initial versions a few years back

  • But your specific app is a player in this, and the only way you can really see if you have a problem, is by testing your app.

    I respectfully disagree. When an app deals with dynamic, user-defined data, it’s essential to have both clear documentation and an API that enables developers to handle system limits gracefully. I can’t stop users from exceeding those limits—but I also don’t want the app to crash when they do. And I shouldn’t be expected to test every possible user configuration across all supported devices.

    A good example of proper API behavior is makeWebRequest, which returns clear, manageable error codes—-403 when it runs out of memory, -402 when the response exceeds the size limit. Why can’t Storage.setValue offer the same kind of feedback? If I receive a large JSON payload from makeWebRequest, how am I supposed to know whether it can be safely stored—or if doing so will crash the app?

    The same issue applies to the Watchdog timer. I’ve implemented a task queue to break up heavy computations, but figuring out how long I can safely run is pure guesswork. If the API simply exposed the remaining Watchdog budget, I could write code that’s far more efficient and resilient. One developer in a recent forum thread mentioned manually timing each function in a loop to estimate Watchdog usage. That’s hardly a sustainable or developer-friendly solution.

    Ironically, makeWebRequest—the most generous API in terms of limits—is also the only one that handles them well. If a JSON payload is just under the -402 threshold and I try to store it, the app may crash. And fully parsing that same JSON could easily trigger Watchdog limits.

    To be clear, all of this can be worked around—I’ve done it, and the app runs reliably. But getting there was unnecessarily painful. With better API support, not only would development be smoother, but we could build more efficient and robust apps overall.

    If you’d like to learn more about my use case, you can find details in the app’s online user manual: https://ohg.the-ninth.com

    Have you tried your app on smaller/midrange/older devices for example?

    I only support relatively recent models with sufficient memory. The Fenix 6 Pro is the oldest device in the supported list. Beyond that, examples include all Venu models, the Venu Active 5 and newer, and all Forerunner models starting from the 955.

  • But your specific app is a player in this, and the only way you can really see if you have a problem, is by testing your app.

    Have you tried your app on smaller/midrange/older devices for example?

  • Understand those limits are based on the specific device as well as your app itself, so it's not that straight forward.

    Exactly—and that’s precisely why it’s so important to document these limits clearly and ensure the API handles them robustly.