RabbitMQ for Seismic Waveforms: Enabling Reliable Data Communication

Utpal Kumar   3 minute read      

Seismic data pipelines need reliable, near-real-time transfer between acquisition, processing, and alerting components — and those components shouldn’t have to know about each other. RabbitMQ is a message broker that sits in the middle, moving waveform messages safely across a distributed system so each piece can run, restart, and scale independently. In this post we publish seismic waveform data and consume it in real time using Python and the pika client.

The one mental model

A message broker decouples senders from receivers. A producer never talks to a consumer directly; it hands a message to the broker, and the broker delivers it:

producer → exchange (routes) → queue (buffers) → consumer (processes).

Because the queue buffers messages, a consumer can be slow, restart, or scale to many workers without the producer ever noticing.

RabbitMQ message flow A producer publishes a message to an exchange, which routes it to a queue, from which a consumer receives and processes it. Producer publishes messages Exchange routes by key / type Queue buffers until consumed Consumer processes messages
The broker's job: accept a message from the producer and route it, via an exchange, into a queue where a consumer can pick it up on its own schedule.

What is RabbitMQ?

RabbitMQ is an open-source message broker that implements AMQP (Advanced Message Queuing Protocol). It enables asynchronous communication by routing messages between producers and consumers through queues and exchanges. That fits seismology well: data producers (stations, telemetry services, ingest pipelines) and data consumers (detectors, pickers, dashboards, archival services) can each run independently.

Key concepts

  • Producer: sends messages.
  • Queue: stores messages until consumed.
  • Consumer: receives and processes messages.
  • Exchange: routes messages to queues.
    • direct: routes using exact routing keys.
    • fanout: broadcasts to all bound queues.
    • topic: routes by wildcard routing patterns.
    • headers: routes by message headers.
  • Binding: rule that connects an exchange to a queue.
Check your understanding

Your consumer crashes for 30 seconds while the producer keeps publishing. What happens to those messages?

Set up RabbitMQ

Requirements

  • Docker (optional, easiest for local setup)
  • Python 3.7+
  • pika Python library

Start RabbitMQ with Docker

docker run -d --hostname rabbit-host --name rabbitmq \
  -p 5672:5672 -p 15672:15672 rabbitmq:3-management
  • AMQP endpoint: localhost:5672
  • Management UI: http://localhost:15672 (default user/password: guest / guest)

Version note (2026): the RabbitMQ 3.x series reached end-of-life on 31 July 2025 and no longer gets security fixes. For anything beyond a throwaway local test, use the current major instead — rabbitmq:4-management. The pika code in this post is unchanged across the two.

Install Python client

pip install pika

Producer: publish seismic waveform messages

Create producer.py:

import json
import pika


def publish_seismic_data(channel, queue_name, data):
    channel.basic_publish(
        exchange="",
        routing_key=queue_name,
        body=json.dumps(data),
    )
    print(f"[x] Sent: {data}")


connection = pika.BlockingConnection(pika.ConnectionParameters(host="localhost"))
channel = connection.channel()

queue_name = "seismic_data"
channel.queue_declare(queue=queue_name)

seismic_data = {
    "station": "ABC",
    "timestamp": "2024-06-16T12:00:00Z",
    "sampling_rate_hz": 100,
    "amplitude": [0.1, 0.3, -0.2, 0.4],
}

publish_seismic_data(channel, queue_name, seismic_data)
connection.close()

Note the exchange="": that’s the default (nameless) exchange, which routes straight to the queue named by routing_key — the simplest possible setup.

Consumer: receive and process in real time

Create consumer.py:

import json
import pika


def callback(ch, method, properties, body):
    data = json.loads(body)
    print(f"[x] Received: {data}")
    # Add detection/picking/alert logic here.


connection = pika.BlockingConnection(pika.ConnectionParameters(host="localhost"))
channel = connection.channel()

queue_name = "seismic_data"
channel.queue_declare(queue=queue_name)

channel.basic_consume(
    queue=queue_name,
    on_message_callback=callback,
    auto_ack=True,
)

print("[*] Waiting for messages. To exit press CTRL+C")
channel.start_consuming()

Run producer and consumer

  1. Start RabbitMQ.
  2. Start consumer first:
python consumer.py
  1. Publish data:
python producer.py

The consumer should print received waveform messages as they arrive.

Optional: route by topic exchange

If you want routing by message type or station family, use a topic exchange.

channel.exchange_declare(exchange="seismic_exchange", exchange_type="topic")
channel.queue_bind(
    exchange="seismic_exchange",
    queue=queue_name,
    routing_key="seismic.#",
)

Publish with a routing key:

channel.basic_publish(
    exchange="seismic_exchange",
    routing_key="seismic.waveform",
    body=json.dumps(seismic_data),
)
Check your understanding

You want every dashboard, detector, and archiver to receive a copy of every waveform. Which exchange type fits best?

Practical seismology use cases

  • Real-time earthquake monitoring pipelines.
  • Distributed waveform processing across worker services.
  • Alerting and notification systems.
  • Reliable buffering before archival or downstream analytics.

Recap

Without scrolling up — can you trace a message? RabbitMQ gives seismic pipelines:

  • A broker that decouples producers from consumers,
  • the flow producer → exchange → queue → consumer,
  • a queue that buffers, so consumers can restart or scale without data loss,
  • and exchange types (direct, fanout, topic, headers) to route messages where they need to go.

Separating who sends from who processes is what makes a monitoring system scalable and fault-tolerant.

Where to go next

Disclaimer of liability

The information provided by the Earth Inversion is made available for educational purposes only.

Whilst we endeavor to keep the information up-to-date and correct. Earth Inversion makes no representations or warranties of any kind, express or implied about the completeness, accuracy, reliability, suitability or availability with respect to the website or the information, products, services or related graphics content on the website for any purpose.

UNDER NO CIRCUMSTANCE SHALL WE HAVE ANY LIABILITY TO YOU FOR ANY LOSS OR DAMAGE OF ANY KIND INCURRED AS A RESULT OF THE USE OF THE SITE OR RELIANCE ON ANY INFORMATION PROVIDED ON THE SITE. ANY RELIANCE YOU PLACED ON SUCH MATERIAL IS THEREFORE STRICTLY AT YOUR OWN RISK.


Leave a comment