architecture · Jun 2025 – Present

Event-Driven Services for High-Volume Energy & EV Data

Designed and scaled event-driven services on AWS EventBridge and SQS with idempotent consumers and retries, and led the Cassandra migration from Astyanax to the DataStax driver.

Role
Event-driven service design, idempotent consumers, and lead on the Cassandra driver migration
Team
Backend engineering
Scope
High-volume concurrent event streams — EV telematics, managed charging, and core energy data — on Bidgely's B2B energy SaaS platform
Level
Software Engineer

Cassandra client library

AstyanaxDataStax

Method: Led the migration of the Cassandra data-access layer across backend services off the legacy Astyanax client to the supported DataStax driver.
Window: during tenure

Event delivery handling

duplicates unsafeidempotent

Method: Design property of the consumers: at-least-once delivery from SQS/EventBridge is handled with idempotent processing and retry on transient failure.
Window: by design

Core services

legacy clientstreamlined

Method: Qualitative outcome of the driver migration and the streamlining of the core microservices and APIs built on top of it.
Window: post-migration

Context

Bidgely is a B2B energy SaaS platform used by utilities. Behind it sit EV telematics, managed charging, and core energy workflows that produce large, bursty, concurrent streams of device data — exactly the kind of workload that punishes tightly-coupled synchronous services.

My part: designing and scaling the event-driven services that process those streams, and leading the migration of our Cassandra data-access layer onto a supported driver.

Why event-driven

If services call each other synchronously, a slow or failing downstream pushes back-pressure all the way to ingestion, and a traffic burst has nowhere to go but the floor. Modeling the data as events on AWS EventBridge and SQS decouples producers from consumers: bursts buffer in durable queues, consumers scale on their own, and a transient downstream failure becomes a retry instead of a cascade.

The cost is eventual consistency and harder end-to-end tracing — a trade worth making for a high-volume, bursty workload where reliability is the point.

Idempotency is not optional

Queue delivery is at-least-once. Retries, visibility-timeout redeliveries, and replays all mean the same event can show up twice. So every consumer is built to be idempotent — keyed on a stable event identity, so processing the same event twice has the same effect as once. That's what makes retries safe, and it's non-negotiable for anything that feeds energy or charging data downstream.

The Cassandra driver migration

The services talked to Cassandra through Astyanax — a client that's deprecated and no longer maintained. Every month on it accrued risk: no upstream fixes, harder onboarding, growing distance from current Cassandra. I led the migration to the supported DataStax driver, and used it as the moment to streamline the core microservices and APIs that sat on top.

The subtle part of a client swap isn't the API surface; it's the defaults. Consistency levels, retry policies, and timeouts differ between clients, and a silent change in any of them changes how your queries behave under failure. I verified read/write behavior matched the old client before cutting each service over.

Outcomes

High-volume concurrent event streams flow through resilient, idempotent event-driven services, and the data-access layer runs on the supported DataStax driver — better performance, better stability, and less standing platform risk.

Decision Records

Where I Got It Wrong

Failure 1

During the driver migration, default consistency-level and retry-policy differences between Astyanax and the DataStax driver meant query behavior could change subtly under the services if taken at face value

Cost: Extra verification work to confirm read/write behavior matched the old client before cutting services over

Lesson: When swapping a database client, treat the default consistency, retry, and timeout settings as part of the contract — they differ between clients, and a silent change in them is exactly the kind of bug that only shows up under failure

Long-Term Impact

Event-driven services with idempotent consumers and the supported Cassandra driver are the foundations the team builds new energy and telematics workflows on.