Promotions, lifecycle and operations
Arguing for the project nobody had funded
Promotions had been built quickly as a small feature: a display name, active or inactive, a start and an end date. They were also responsible for roughly a tenth of platform revenue, and account managers were tracking hundreds of them in side spreadsheets because the product could not tell them what state anything was in.

Five explicit states in the table, and an expired promotion one click from reactivation.
Context
We earn on a cost per install basis from the offers shown inside Playtime, and promotions are one of the strongest levers on that. They had been built early as a deliberately small feature and never revisited: a name, a binary status, two dates. Account managers ran hundreds of them through that interface, using external trackers to keep hold of what was live, what was queued and what had lapsed. The first thing I did was unrelated to the lifecycle. I linked each promotion to the publisher using it, because the table gave no context about who a promotion belonged to.

Before. Two statuses, no filtering, no date range. Everything a person needed to know about timing had to be inferred from the name or tracked somewhere else.
Tension
The design was not the hard part. Securing the investment was. Promotions sat in the backlog behind several much larger initiatives, and the honest internal view was that it already worked. To change that I had to make the cost of leaving it alone visible. I put a number on the revenue promotions were responsible for, roughly ten percent of platform revenue, which had been broadly understood but never quantified. Then I documented the hidden operational cost: the hours account managers spent reconciling a table against their own side apps, and the risk that a promotion runs past its window or never starts because nobody noticed. Presented together, as recurring cost against unrealised revenue, the project got prioritised. Getting the buy in took longer than the design.
Insight
Promotions already had a lifecycle. It was running in production every day and the product simply refused to acknowledge it. A promotion is scheduled, becomes active, expires, and if it recurs it returns to scheduled. Separately it can sit half configured as a draft, or be parked as inactive. Six behaviours were being flattened into one binary flag, so account managers rebuilt the missing model in spreadsheets. My job was not to invent a system, it was to surface one that was already there.
The lifecycle was not missing. It was running in production and had never been written down.
Decisions, and what each one cost
Impact
Measured over two months on a base of several hundred promotions. The gap between the two numbers is the part I find interesting: account managers gained more than publishers did, which fits, because they manage volume and were the ones losing time to spreadsheets. The publishers with access are a small self serve group and are less promotion driven than we are.
More: the system underneath, screens, leadership and step by step
The system underneath
Five states, with the transitions that actually occur. The happy path is a loop rather than a line, which is the detail the original two state model could not express.
- Created, waiting
- Returns here if recurring
- Running now
- Changing it asks first
- Window closed
- Reactivate via modal
- Form half filled
- 10 to 20 inputs, saved partway
- Parked deliberately
- Not derivable from dates
Scheduled, active and expired form the recurring loop. Draft and inactive sit outside it, and are the two states no date based logic could ever produce, which is why they had been invisible.
The model, and the two places it needed friction

Five lifecycle states made explicit in the table, with filtering, search and a date range control in the top bar. Previously this was a binary flag and a search box.

The lifecycle as it already ran in production. The loop is the part a date comparison can express. Draft and inactive are the part it cannot, which is why they had been invisible.

Friction added on purpose. Editing or deactivating a running promotion changes what real users see immediately, so both state the consequence before they proceed.

Friction removed on purpose. An expired promotion returns by setting a new window rather than reopening the full creation form, because the rest of its configuration is already correct.

Five dimensions to filter, and the date range rule. A promotion is returned if it touches the window at any point, because account managers think in windows rather than in whole promotions.
Leadership and ownership
- Making an invisible cost visibleNobody was arguing that promotions worked well. They were arguing that other things mattered more. I quantified the revenue promotions carried and documented the operational time account managers were losing to external trackers, then presented both as an ongoing cost rather than a feature request.
- Disagreeing with my PM on purposeThe PM wanted no confirmation dialogs, for consistency with everything else in the product. I pushed for two, argued from a specific class of past incident and the asymmetry of the actions, and shipped them. Being consistent was the weaker argument here.
- Accepting a correction in reviewThe date picker was in the wrong place and an internal review caught it. It was my inconsistency to fix, and I would rather absorb a revision than weaken a pattern the rest of the product depends on.
How it works, step by step
- See state at a glanceEvery promotion carries its actual lifecycle state in the table, so the question of what is live right now stops requiring a side app.
- Filter instead of guessStatus, publisher, application and active date, with sortable columns, so finding a set of promotions no longer depends on how someone titled them.
- Set a date rangeA range control in the top bar for checking everything active or planned within a window, which is how account managers actually think about their month.
- Change a running promotion, deliberatelyEditing or deactivating something that is live asks for confirmation and states the consequence, because end users are already seeing it.
- Reactivate without rebuildingAn expired promotion can be brought back through a short modal rather than the full creation form, since the configuration is already correct.
Looking back
This is the case I would use to explain what changes at senior level. The design was not difficult, and a mid level designer could have drawn it. The work was proving that a feature everyone considered finished was quietly costing us revenue and operational hours, and turning that into funded engineering time.



ME
DÖ
P
UY