What is a Permanent Controller?
By default, GetX automatically disposes controllers when they are no longer in use (e.g., when a route is popped). A permanent controller is one that never gets disposed automatically. It lives for the entire lifetime of the app, making it ideal for global services like authentication, theme management, API clients, or any shared state that must persist across routes.
Creating a Permanent Controller
To make a controller permanent, set permanent: true when registering it with Get.put or Get.lazyPut.
You can also use GetxService, which is a convenience class that is already permanent by default.
Permanent vs Non-Permanent
When to Use Permanent Controllers
- Authentication state – User login status should survive across screens.
- Theme / settings – App-wide preferences that should persist.
- API services – Dio client, database connections, etc.
- Notification handlers – Services that listen for push notifications.
- Analytics – Track user sessions across the whole app.
Lifecycle of a Permanent Controller
A permanent controller is created once (when first registered or accessed, if lazy) and never disposed unless you manually call Get.delete. Its onInit() is called once, and onClose() is called only when you delete it manually.
Permanent Controllers in Bindings
You can register permanent controllers in bindings. They will be created when the route is first opened and remain alive even after the route is closed.
Accessing Permanent Controllers Anywhere
Because they are permanent, you can access them from any controller, widget, or service using Get.find<MyController>() at any time.
Best Practices
- Use
GetxServicefor app-wide services – It clearly communicates intent and is permanent by default. - Limit permanent controllers – Only for truly global dependencies. Overusing them can lead to memory bloat.
- Dispose resources manually when needed – If your permanent controller holds streams or timers, close them in
onClose(which you may call manually when the app terminates). - Avoid holding large data in permanent controllers – Prefer caching strategies that can be cleared.
- Test with
Get.reset()– In unit tests, reset the dependency container to avoid state leakage.
Common Mistakes
- ❌ Making every controller permanent – Unnecessary memory usage. ✅ Use permanent only for global services.
- ❌ Not cleaning up resources – Even permanent controllers should close streams in
onCloseif they are ever deleted manually. ✅ OverrideonCloseand dispose resources. - ❌ Registering a permanent controller inside a widget's
build– Causes re‑registration and potential leaks. ✅ Use bindings or initState. - ❌ Assuming permanent controllers are automatically disposed – They are not; you must call
Get.deleteif you ever need to remove them.
FAQ
- Q: What's the difference between
permanent: trueandGetxService?
A:GetxServiceis a convenience class that already haspermanent: trueset. It's the recommended way for app‑wide services, but both work identically. - Q: Can I make a permanent controller lazy?
A: Yes, useGet.lazyPut(() => MyController(), permanent: true). It will be created on first access and never disposed. - Q: How do I manually delete a permanent controller?
A: CallGet.delete<MyController>(). This will callonClose()and remove it from the registry. - Q: Will a permanent controller survive a hot restart?
A: Hot restart re‑runsmain(), so all controllers are re‑initialized. They will be recreated. - Q: Should I use
permanentfor a controller that holds a WebSocket connection?
A: Yes, that's a good use case. But remember to close the connection inonCloseif you ever delete the controller (or in aclosemethod).
Conclusion
Permanent controllers are a powerful feature in GetX that let you create global, long‑lived dependencies. By using permanent: true or GetxService, you can manage app‑wide state and services with ease. However, use them judiciously to keep your app memory‑efficient.