Overview
Prepaid Expiration Reminders is a scheduled, event-driven automation I built into the networking backend of a fiber-optic ISP. Prepaid customers buy an internet package that lasts a fixed number of days; when it expires, their service is cut off. On a fixed schedule the system scans active contracts, works out who is about to run out, applies a set of timing rules, and hands each due reminder off for delivery — so customers renew on time instead of losing their connection. The heart of it isn’t the sending; it’s the decision of who to remind and when. I built it with Python on AWS Lambda and AWS CDK.
The problem
Prepaid subscribers had no automated heads-up before their package expired. They would simply lose internet, then contact support or churn — a bad experience for the customer and lost recharge revenue for the ISP. The business needed a hands-off, reliable way to nudge each customer at the right moment before expiration, across the channels customers actually use, without spamming them with duplicate reminders.
What I built
- Scheduled reminder Lambda — an AWS Lambda that pulls active prepaid contracts, computes the days remaining until each package expires, and decides who to notify.
- Tiered reminder rules — a rule engine that scales the lead time to the package length, so short packages are reminded close to expiry while longer ones get more runway. Each customer is reminded on exactly the right day, not on every run.
- Decoupled dispatch through Amazon SQS — rather than deliver inline, the Lambda enqueues one message per due reminder onto an SQS queue. That decouples “who to remind” from “send it”: delivery runs on its own, absorbs retries, and scales independently of the scan.
- Delivery is delegated, not reimplemented — the actual sending is handed to the separate Push Notification Service (another backend I built), which drains the queue and delivers each reminder over push (Amazon SNS), WhatsApp, and SMS as three independent channels. This pipeline owns when and to whom; that service owns how it’s sent.
- History & de-duplication — every notification is written to a database that doubles as an audit history and an idempotency guard, so a customer never gets the same reminder twice even if a message is retried or redelivered.
Architecture
The system is event-driven and fully serverless — there are no servers to keep running and no polling loop of my own; AWS drives the schedule:

- Amazon EventBridge Scheduler fires on a schedule, pinned to the local timezone.
- The scheduler assumes a dedicated IAM role whose inline policy grants only
lambda:InvokeFunctionon the reminder function — least-privilege by design. - It invokes the reminder Lambda, with AWS X-Ray tracing enabled and its dependencies provided as a Lambda layer.
- The Lambda reads active contracts, enriches each with customer data, runs the tiered rules, and — for every customer due today — enqueues a message onto Amazon SQS.
- Amazon SQS buffers the reminders and hands them to the Push Notification Service, which processes them concurrently and delivers over push, WhatsApp and SMS, then writes each result to the notification record (history + duplicate protection).
Impact
The ISP gained a zero-maintenance reminder loop that turns silent expirations into timely recharge nudges. Customers get warned before they lose service — with the lead time scaled to how long their package lasts — which protects the subscriber experience and the recharge revenue that used to leak away when packages quietly ran out. As infrastructure as code, the whole system deploys and tears down with the rest of the networking stack and can be enabled per environment.