Is mirroring Stripe (Subscriptions, Invoices, Coupons…) in your own local database efficient?

Is mirroring Stripe with your own local database is a good thing?

Mirroring using both API calls (create a new plan, coupon, subscription, etc.) and webhooks (new invoice or charge generated, payment failed.) so you can store all data (literally have similar tables with columns matching the stripe objects) locally and work with it faster.

Read More

If not, what data do you save locally and what do you request?

Thank you.

Related posts

3 comments

  1. Typically, saving the same data in two different places is not a good idea. By avoiding data duplication, you save a lot of time and prevent possible issues like data being out of sync.

    That being said,

    1. You do not control data saved on Stripe’s side. If it disappears for any reason, you are in trouble. Even though such an event is highly unlikely, I would recommend to store locally the most critical information.

    In my apps I typically store Stripe’s customer ID and which plan a user is subscribed to. Obviously, I also have all plans in my code since they determine what a user can do within an app.

    1. You may want to store some data locally for performance reasons, but a call to your own database is not necessarily faster than an API call. More importantly, even if there is a difference of a few hundred milliseconds, users will not notice it. And most users access such data (list of their invoices, etc.) very infrequently.
  2. Like Andrei said, it is nice to not have to worry about data duplication issues. Their API is plenty fast for most use cases, but if you need to make it faster, you can create temporary caches using redis or memcached. This is especially important if Stripe’s API has any unexpected downtime.

    Most SaaS companies like Stripe recommend backing up your data as an extra precaution. So if some of your Stripe data is accidentally deleted, or a Salesforce contact is changed, etc… then you can always recover it from a backup. This also covers you in the very unlikely event that Stripe’s data is compromised.

    Seems unlikely but you never know if you don’t control it yourself. Capital One was hacked last year and I would’ve never thought it would happen.

  3. The strategy you’re describing is exactly the one I am using.

    Basically, using Stripe is a bidirectional thing: sometimes you initiate the request (when creating a new customer for example), sometimes they do (when canceling a subscription because a credit card is failing for example).
    In the first case I save the Stripe response (which is a JSON) in my database. In the second case, I save the Stripe webhook (which is a JSON too) in my database too.

    In order not to choose which customer or subscription fields to save in DB, I save the whole JSON in PostgreSQL using a JSONB field. There is almost no performance overhead, and it is very simple to query the data.

    Doing this you have the best of both worlds:

    • Speed (since you are reading local data instead of remote data)
    • Ease of development (you don’t have to think to much about which Stripe data you are going to save)
    • You’re safe in case of disaster on the Stripe side
    • You data is always up to date

    I actually even wrote an article about that, in case it helps:
    https://juliensalinas.com/en/storing-stripe-payment-data-database/

Comments are closed.