The long-term goal is to deprecate and replace Shuttle Persist with more sophisticated key-value or blob storage solutions. When that happens, migrating saved Persist data to the new services will be possible.

The persist plugin allows anything that implements serde::Serialize and serde::Deserialize to be persisted in a key-value store on the filesystem, and persist between deployments. This is useful for saving and retrieving data when it is not desired to hard code that data into the app. An example is saved settings for a Discord bot that need to remain the same between updates. State data, used in web frameworks such as Axum and Rocket, is also a good candidate for use of the persist plugin.


To use the persist plugin, add shuttle-persist to the dependencies of your service with cargo add shuttle-persist. Then, annotate your shuttle_runtime::main function by adding the shuttle-persist::Persist attribute as a parameter. This will give a PersistInstance. The methods available are:

  • save(): saves a key-value pair
  • load(): loads the value stored in a key
  • remove(): deletes a key
  • list(): returns all the keys as a vector of strings
  • clear(): deletes all keys


This snippet shows a Shuttle rocket main function that uses the shuttle_persist::Persist attribute to provision and get access to a PersistInstance. In this example, the PersistInstance is used to store state for the app.
async fn rocket(
    #[shuttle_persist::Persist] persist: PersistInstance,
) -> ShuttleRocket {
    let state = MyState { persist };
    let rocket = rocket::build()
        .mount("/", routes![retrieve, add])


The full example can be found on GitHub.