Eventum Logo

Eventum

Realistic test data: behaving like production

Why uniform random output looks synthetic, and the techniques that make it behave like production traffic.

A generator that fires events at a perfectly steady rate and picks every value uniformly at random is simple to build — and the easiest kind of synthetic data to spot. Real traffic rises and falls through the day, groups itself into sessions, carries a shared identifier across related events, and clusters around common values instead of spreading evenly. Data that ignores that still fills a schema, but it never behaves like the traffic it stands in for.

What makes synthetic data realistic

Several properties separate data that behaves like production from data that only fills a schema, and each is independent of the others:

  • Timing — real traffic is not a flat stream. It rises during business hours, bursts around specific triggers, and goes quiet at night or on weekends, following a rhythm instead of a constant rate.
  • Sessions and state — real activity is rarely a set of independent events. A login precedes a stretch of activity and ends with a logout, and each step depends on what happened earlier in the same sequence, not on a fresh random draw.
  • Correlated events — related events tie together across a stream instead of merely sharing a field by coincidence. A shared identifier carries unchanged through every event a flow or a request touches, and a per-host sequence number orders them exactly.
  • Values — real measurements are rarely spread evenly across a range. Most fall near a common case with a long tail of larger outliers, and categorical values such as status codes or protocols skew toward the common ones rather than splitting evenly.

Getting one axis right without the others still produces a giveaway: perfectly even timing paired with skewed values reads as a load-test script. Sometimes the more direct move is to skip shaping any of this by hand and reuse a real capture that already has it built in — replaying an existing log with fresh timestamps rather than generating a new approximation of it.

How Eventum generates it

Eventum exposes each axis as something you configure, not a fixed default:

  • Timing — the time_patterns input plugin replaces a flat cron or timer schedule with a repeating time window, a baseline volume, and a distribution that places timestamps inside each window, so the timing itself carries a daily or weekly rhythm.
  • Sessions and state — the template event plugin's mode: fsm turns a set of templates into states connected by transitions, paired with state that carries a session id or counter across the sequence.
  • Correlated events — a shared pool keyed by correlation id, rendered through mode: all instead of a state machine, ties together several concurrent threads — a flow, a request-response pair — that all run at once.
  • Values — the same plugin fills in values with module.rand's skewed distributions — log-normal for byte sizes, exponential for durations, Gaussian for metrics — plus weighted choice for categories, Faker- and Mimesis-backed fields, and pre-built sample datasets.
  • Replay — the replay event plugin skips generation altogether and reads an existing log file back, rewriting only the timestamps it finds to the moment each line is actually replayed.

On this page