When a service becomes expensive to run, adding infrastructure is only one possible response. First, follow the data. A small event can cross several services, carry an unnecessary image and reach clients that never needed it.

Draw the complete request journey

List each hop from the source to the final consumer. For an event-driven system, that might include an incoming webhook, a relay, a Rails application and a connected device. Record which service owns each step and which data the next consumer actually needs.

Include retries and reconnections in the map. The intended path and the path taken during a failure may be very different.

Measure bytes as well as requests

Request count alone does not explain traffic volume. Compare payload sizes, destinations and repeat frequency over the same observation window. Distinguish a measurement taken from a short test from a monthly billing total.

Then ask concrete questions: are we forwarding the same data repeatedly? Does every device need every event? Can a consumer fetch a large attachment only when it is needed?

Choose a change with a measurable target

Possible changes include sending a smaller event, narrowing the recipient list or removing an unnecessary forwarding hop. Each needs a correctness check. A lower traffic number is not a useful result if an alert arrives late or a device misses it.

When handling large data inside a Node service, also consider how it moves through memory. The Node stream documentation explains backpressure, which is relevant when a downstream consumer cannot keep up with incoming data.

Compare the same workload

Validate before and after using a comparable workload and observation period. Track event delivery, errors and resource use together. Keep the measurement method with the result so someone else can reproduce the comparison.

At MIC Labs, we prefer to identify the expensive path before choosing the infrastructure change. That turns a general cost concern into a bounded engineering task.