Pin Abstarct
Pin Abstarct
Abstract

our own products · multi-tenant saas

our own products · multi-tenant saas

We have been running multi-tenant Rails in someone else's platform since 2020

Ruby on Rails software that still works in year five.

We have been running multi-tenant Rails in someone else's platform since 2020

Ruby on Rails software that still works in year five.

Six apps. 895+ active merchants. More than twenty forced API migrations. Nobody ever approved a budget for a single one of them.

Six apps. 895+ active merchants. More than twenty forced API migrations. Nobody ever approved a budget for a single one of them.

6 yrs live

20+ API migrations

5,000 webhooks a day

0 downtime from a version change

built for shopify

AI Product Bundle Builder carries Shopify's Built for Shopify designation.

Shopify awards it to apps meeting its highest standards for performance, design and integration. It is audited against measured performance on real merchant storefronts, and it can be taken away. That is not a badge we gave ourselves.

4.7

rating, 21 reviews

650+

merchants on this app

  • Client Logo
    GCS Medical College, Hospital and Research Centre, Ahmedabad logo
    Vedica logo
    Bancr logo
    Client Logo
    Unimed Living logo
    Client Logo
    Client Logo
    Client Logo
    Client Logo
    Client Logo
    Client Logo
  • Client Logo
    GCS Medical College, Hospital and Research Centre, Ahmedabad logo
    Vedica logo
    Bancr logo
    Client Logo
    Unimed Living logo
    Client Logo
    Client Logo
    Client Logo
    Client Logo
    Client Logo
    Client Logo

0-4 yrs

0-4 yrs

average client relationship, in an industry that measures it in months

average client relationship, in an industry that measures it in months

20%

20%

of annual revenue from clients partnering with us for over two years

of annual revenue from clients partnering with us for over two years

5

5

full-time senior Rails engineers in Ahmedabad, plus architecture & DevOps

full-time senior Rails engineers in Ahmedabad, plus architecture & DevOps

100+

100+

products delivered across proptech, fintech, health, IoT and SaaS

products delivered across proptech, fintech, health, IoT and SaaS

why we published this

Most agencies say they can build multi-tenant software. We run six of them in public.

Most agencies say they can build multi-tenant software. We run six of them in public.

Our sister brand Essenify publishes six apps in the Shopify App Store. They are Ruby on Rails applications serving close to nine hundred independent merchants, each with their own catalogue, their own currency, their own theme and their own idea of what a bundle should do. The oldest has been live since May 2020, and you can install any of them in ninety seconds.

We are not writing this to sell you Shopify work. We are writing it because these apps are the clearest evidence we have of how we build and how we maintain, and unlike a client project, we can show you every part of it.

the constraint

An app store is a harder test than a client project

An app store is a harder test than a client project

A client project has a client. Scope gets agreed. Deadlines move when they have to. If something breaks at 2am on a Sunday, there is usually a conversation about it on Monday. An app store has none of that.

The platform sets the deadline

Shopify ships a new API version every quarter and supports each stable version for a minimum of twelve months. Miss the window and requests stop working. Nobody raises a ticket. The date arrives, and either you migrated or your merchants wake up to a broken store. Since May 2020 that has happened more than twenty times to our bundle app alone.

The quality bar is external

Built for Shopify is awarded by Shopify, audited against measured performance on real merchant storefronts, and it can be taken away. We did not set the standard and we cannot grade ourselves against it.

Every merchant has production data

There is no staging environment where a mistake is cheap. A bad migration touches hundreds of live stores taking real orders, in real currencies, on a real Tuesday.

the engineering, honestly

Three problems that only show up at this scale

Three problems that only show up at this scale

Multi-tenancy under load, quarterly platform migrations, and webhook volume that arrives out of order and twice.

01

Multi-tenancy under real load

Six applications, close to nine hundred stores. Each merchant's data is isolated, each has their own configuration, their own installed theme, and their own set of active bundles. A single deploy has to be correct for all of them at once.

Every tenant-owned table is scoped by shop_id. It is the single partitioning key across the schema, covering products, bundles, configuration and inventory sync records. That scoping is also what handles merchants with unusually large catalogues: their queries are narrowed to their own rows from the start, so catalogue size does not create contention with anyone else's data.

On the processing side, each shop runs its own queue, so jobs are worked through with per-shop priority instead of competing in one shared queue. A large merchant's bulk sync or bundle recalculation does not delay processing for a smaller shop sitting on the same deploy.

The bundle app alone supports fixed bundles, mix and match, build your box, volume tiers, Buy X Get Y, and frequently bought together, with inventory syncing per SKU so a bundle cannot oversell a component that has run out. That inventory sync is the part people underestimate. It has to hold when two shoppers hit the same last unit through two different bundles in the same second. The app calculates the quantity to deduct for each component in a bundle purchase and fires the decrement directly to the Shopify Inventory API, so stock levels stay accurate against what is actually left, whichever bundle type pulled from that SKU.

02

Surviving quarterly API migrations without merchants noticing

The mistake almost every app makes is scattering API calls through the codebase with the version string embedded at each call site. When the version sunsets, the migration becomes an archaeology project across dozens of files, done under a hard deadline, with no way to test the new version without breaking the old one.

Our approach is to keep the platform at the edge of the application. Every Shopify API call goes through a wrapper class rather than being called directly from business logic, so the version in use is a configuration value set per environment, not something baked into individual call sites. That means we can point a staging environment at the new version, run against it, and migrate whatever call sites actually changed while production keeps running the current version untouched. The domain code on top never has to know the difference.

A real breaking change, caught early

An API version stopped sending location_id on orders, which we had relied on directly. The fix was not a workaround at the call site. It meant fetching the fulfillment location through the Fulfillment API instead and deriving the location from there.

Because the version was isolated to one layer, that was a contained change inside the wrapper rather than a hunt through every place location_id was used.

03

Webhook handling that does not lose events

Shopify sends webhooks for orders, product changes, app uninstalls and mandatory compliance requests. They arrive out of order. They arrive twice. Sometimes they do not arrive at all, and sometimes they all arrive at once because a merchant just bulk-edited four thousand products.

An app that treats a webhook as a simple HTTP handler will lose data. The handler has to acknowledge quickly, do the work in the background, and be safe to run twice on the same event.

Across the six apps we see 4,000 to 5,000 webhooks a day, spiking well beyond that during high-traffic periods like Black Friday. The handler's job is deliberately thin: acknowledge with a 200 immediately on receipt, enqueue the work as a Sidekiq job, and let the queue process it. That separation is what keeps webhook delivery from ever blocking on however long the actual processing takes.

There is no single idempotency mechanism shared across all six apps, because each app's handling of a duplicate webhook depends on what that webhook is doing. On the bundle app, inventory is calculated from order state rather than applied as a delta per event, so a repeated order webhook does not double-reduce stock. Other apps handle their own webhook-triggered actions according to what they do, rather than relying on one universal dedup rule.

Failed jobs fall back to Sidekiq's standard retry behaviour, so a failure is retried automatically rather than silently dropped. The mandatory GDPR compliance webhooks are handled directly: on customers/redact and shop/redact, the shop's data is actually removed rather than flagged or anonymized.

04

Logic split across two runtimes

The bundle app uses cart transforms and a checkout extension, which means part of the pricing logic runs inside Shopify's own infrastructure rather than in our Rails app. Splitting logic across two runtimes, where one of them you cannot debug directly, is its own discipline.

Built for Shopify is assessed on real storefront performance, not on a Lighthouse score in your own browser. The bundle widget renders inside a merchant's theme, on their hosting, alongside every other app they have installed, on a shopper's phone.

how it runs

Nothing changes on day one

Nothing changes on day one

We work in your existing codebase, in your existing repository, behind your existing tests. Value arrives from the first month rather than at the end.

01

A workshop first

Half a day with the people who use the product daily. They will tell you where the manual work is faster than any audit will.

02

A prioritised list you approve

Every item with what it does, what it costs and what it saves. You pick the order, and you can stop after any item.

03

Shipped in slices

A live URL every week. Each improvement goes out on its own rather than waiting for a big release.

04

Your team keeps working

We fit around your roadmap rather than freezing it. Nothing we do blocks a release you already planned.

what this means if you are hiring us

Three things, and they are the reason this page exists

We publish this because it is the only work we can show you in full detail, including the parts a client NDA would normally hide.

We maintain software on a schedule we do not control

When we sell you a Rails care plan, we are not describing a service invented for a pricing page. It is what we do to our own products every quarter, on a deadline, with our own revenue on the line if we get it wrong.

We know what a platform upgrade actually costs

We have paid it more than twenty times. That is why our Rails upgrade advice is one minor version at a time with the suite green at every stop. It is not a philosophy. It is what we learned by doing the alternative once.

We have run production systems long enough to be pessimistic in useful ways

Thin handlers, retries, per-tenant queues, and a plan for the webhook that arrives twice. These are habits from operating our own software, not chapters from a book.

where to start

Start with automation

Start with automation

It pays for itself fastest and it needs no design decisions or model choices. Find the three things your team does by hand every week and remove them. The saved hours fund the rest of the programme, and it proves the process before anyone commits to a larger budget.

Then intelligence or interface, depending on where the pressure is. Internal efficiency points to intelligence. How you look next to a competitor points to interface.

Apps live in the Shopify App Store

6

Active merchants across all apps

895+

Oldest app launched

26 May 2020

API versions migrated since launch

20+

Webhooks processed daily

4,000 to 5,000

Built for Shopify certified

AI Product Bundle Builder

Rating, AI Product Bundle Builder

4.7★ (21 reviews)

Languages supported

English, French, German

Stack

Rails, Shopify Functions, Sidekiq

The six apps

AI Product Bundle Builder

AI Product Bundle Builder

650+ merchants

650+ merchants

Discountify

Discountify

120+ merchants

120+ merchants

FAQ Expert: Page, Product FAQs

FAQ Expert: Page, Product FAQs

55+ merchants

55+ merchants

AddOn Suggest: Product Upsell

AddOn Suggest: Product Upsell

30+ merchants

30+ merchants

Product Quiz Builder

Product Quiz Builder

20+ merchants

20+ merchants

Bulk Price Updater

Bulk Price Updater

20+ merchants

20+ merchants

two brands, one team

On Essenify, we are the client

Essenify is our product brand and Essence Solusoft is our engineering studio. Same office, same engineers, same standards. The difference is that on Essenify we are the client, which means every shortcut we might have taken is one we would have had to live with. If you run a Rails application that has to keep working while a platform changes underneath it, that is the problem we have been solving on our own money since 2020.

essence logo

two brands, one team

On Essenify, we are the client

Essenify is our product brand and Essence Solusoft is our engineering studio. Same office, same engineers, same standards. The difference is that on Essenify we are the client, which means every shortcut we might have taken is one we would have had to live with. If you run a Rails application that has to keep working while a platform changes underneath it, that is the problem we have been solving on our own money since 2020.

essence logo

two brands, one team

On Essenify, we are the client

Essenify is our product brand and Essence Solusoft is our engineering studio. Same office, same engineers, same standards. The difference is that on Essenify we are the client, which means every shortcut we might have taken is one we would have had to live with. If you run a Rails application that has to keep working while a platform changes underneath it, that is the problem we have been solving on our own money since 2020.

essence logo

Direct Access

Tell us about your project.

A senior Rails engineer reads every message received here. Expect a direct response within one working day.

Direct WhatsApp / Phone

Start Your Rails Project

Strict NDA Protected • 100% Confidential

Direct Access

Tell us about your project.

A senior Rails engineer reads every message received here. Expect a direct response within one working day.

Direct WhatsApp / Phone

Start Your Rails Project

Strict NDA Protected • 100% Confidential

Direct Access

Tell us about your project.

A senior Rails engineer reads every message received here. Expect a direct response within one working day.

Direct WhatsApp / Phone

Start Your Rails Project

Strict NDA Protected • 100% Confidential