Merging the ACE AddonSettings tables for multiple apps

We have a number of atlassian-connect-express (ACE) apps deployed to Heroku.

Each ACE app has both a “production” and “staging” Heroku environment (so two Heroku apps for every ACE app).

Each Heroku app has its own Heroku Postgres db, which in most cases will contain just the AddonSettings table that ACE uses to track installs.

For many years we have been able to get by using Heroku’s free Postgres tier, as the number of installs per app/environment remains well under the 10k row limit of Heroku’s free tier.

With the recent announcement by Heroku that they are removing their free tier, we are in the process of upgrading these dbs to Heroku’s new “Mini” Postgres plan, which has the same 10k row limit that the free tier did but now carries a $5/month/db cost.

Heroku does allow a Postgres database to be shared between multiple apps, so to save costs we’re looking at consolidating some of these databases.

In particular, staging apps typically each only have one or two rows in their AddonSettings table.
So rather than an ongoing monthly cost of number of apps * $5, it makes sense for all of our staging apps to share a database.

As a test, we successfully merged the data from all staging dbs into a single Postgres instance, and tested that all installed apps still function as expected in our staging environments.

My question is around duplicate clientKey values.

After merging the AddonSettings rows from different apps, we now have a few rows that have the same clientKey.

For example, if two Confluence apps (app-1 and app-2) are both installed in our Confluence staging environment (<staging-env>.atlassian.net), then before the merge we would have something like:

Database for app-1 - AddonSettings

id clientKey key val
1 AAAA… clientInfo {“key”: “com.foo.bar.app-1”, … }

Database for app-2 - AddonSettings

id clientKey key val
1 AAAA… clientInfo {“key”: “com.foo.bar.app-2”, … }

After the db merge, we end up with:

Shared database for app-1 & app-2 - AddonSettings

id clientKey key val
1 AAAA… clientInfo {“key”: “com.foo.bar.app-1”, … }
1 AAAA… clientInfo {“key”: “com.foo.bar.app-2”, … }

In our testing, this doesn’t seem to cause any problems with already installed apps; but looking through the code in ACE it seems to mainly lookup rows by clientKey + key, which would suggest that it isn’t really intended to have multiple ACE apps sharing a single AddonSettings table, and that if we were to try to register an new app install it would probably break.

Can anyone that has some knowledge of ACE (and the AddonSettings table that it manages) confirm if it is possible/advisable to have multiple apps use a single shared database?

Actually, I’ve just noticed that you can configure the name of the table that ACE uses (defaults to AddonSettings).

So rather than trying to shoehorn all of our apps into a single AddonSettings table in one database, we could simply configure each app to use a different table name in that same shared db, e.g.

"store": {
  "adapter": "sequelize",
  "type": "postgres",
  "url": "$DATABASE_URL",
  "logging": false,
  "table": "App1AddonSettings"   // <- app-1
}

"store": {
  "adapter": "sequelize",
  "type": "postgres",
  "url": "$DATABASE_URL",
  "logging": false,
  "table": "App2AddonSettings"   // <- app-2
}

...etc.
2 Likes

Thanks for the Heroku 28 Nov deadline reminder. I’ve found the ‘mini’ postgres option for $0.01/m - haven’t tested it though.

Another option is to use another postgres “schema” in the database, and connect to this schema instead of the default “public” schema.