- Home
- Destinations
- MySQL
Send events to MySQL
Row-shaped event delivery into a customer-owned MySQL table, INSERT IGNORE by primary key, idempotent.
What is MySQL?
MySQL is the second most-deployed relational database after Postgres and the default in many older application stacks. As a destination, it serves the same use cases as Postgres, events alongside the customer's operational data, for teams already on the MySQL side of the database fence. Pushrail's adapter writes the same shape, swapping JSONB for the JSON column type and `ON CONFLICT` for `INSERT IGNORE`.
Why deliver events to MySQL
- Same database as the customer's app, joins against domain tables are trivial.
- JSON column type stores arbitrary payloads.
- Aurora and managed-MySQL parity, works on RDS MySQL, Aurora, Cloud SQL, and self-hosted.
- In-app analytics directly over the customer's existing database.
How Pushrail delivers events to MySQL
The adapter writes one row per event with `INSERT IGNORE INTO …` keyed on `event_id` (BINARY(16) PK) so re-runs are naturally idempotent. Columns are `event_id`, `event_type` (VARCHAR(255)), `occurred_at` (DATETIME(3)), `customer_external_id` (VARCHAR(255)), `source` (VARCHAR(255)), `payload` (JSON), `metadata` (JSON), `received_at` (DATETIME(3) DEFAULT CURRENT_TIMESTAMP(3)).
Auth and credentials
Username/password over TLS or AWS IAM authentication for RDS MySQL / Aurora (recommended for AWS-hosted). Credentials encrypted at rest. The customer creates a `pushrail_writer` user with `INSERT` on the destination table only.
Batching, retries, and replay
Inserts are batched 1,000 rows per multi-VALUES statement with a 1-second flush window. Transient errors (connection reset, deadlock) retry with exponential backoff. Permanent errors (auth, table not found) land in the DLQ. `INSERT IGNORE` keyed on the `event_id` makes replay a no-op for already-inserted rows.
Example payload
Pushrail accepts the canonical event shape on POST /v1/events. Below is the ingestion request your service makes.
{
"eventType": "order.completed",
"occurredAt": "2026-05-26T14:21:08.493Z",
"source": "billing-service",
"customerExternalId": "acct_8K2zRq",
"idempotencyKey": "order_38a91f-completed",
"correlationId": "req_4f30b2",
"payload": {
"orderId": "ord_38a91f",
"amount": 12900,
"currency": "USD",
"items": [
{ "sku": "PR-PRO-MONTHLY", "qty": 1, "price": 12900 }
]
},
"metadata": {
"tier": "pro",
"region": "us-east-1"
}
}Example configuration
The fields your customer fills in to point Pushrail at their MySQL setup.
{
"type": "MYSQL",
"name": "Customer MySQL",
"host": "acme-prod.cluster-abc123.us-east-1.rds.amazonaws.com",
"port": 3306,
"database": "acme_app",
"table": "pushrail_events",
"tls": true,
"auth": {
"mode": "RDS_IAM",
"username": "pushrail_writer",
"region": "us-east-1"
},
"batchSize": 1000,
"flushIntervalSec": 1
}Common use cases
- MySQL-first teams who need events alongside their operational data.
- Audit-trail tables with transactional guarantees.
- Reporting over events from a tool that talks MySQL.
- In-app dashboards over event history without a separate warehouse.
Related destinations
Row-shaped event delivery into a customer-owned Postgres table, UPSERT by primary key, idempotent.
High-throughput row-shaped event delivery into a customer's ClickHouse cluster, one row per event.
Stream events directly into a customer's BigQuery dataset, table per event type or single wide table.
Frequently asked questions
How does Pushrail write events into MySQL?
One row per event using INSERT IGNORE INTO … keyed on event_id, so re-runs are naturally idempotent. The columns mirror the canonical envelope with the payload and metadata stored in JSON columns. It serves the same use cases as the Postgres adapter for teams on the MySQL side.
Which MySQL deployments are supported?
RDS MySQL, Aurora, Cloud SQL, and self-hosted MySQL. Pushrail connects with username/password over TLS or AWS IAM authentication for RDS MySQL and Aurora (recommended for AWS-hosted).
Whose credentials are used?
The customer's. They create a dedicated pushrail_writer user with INSERT on the destination table only. Credentials are stored encrypted at rest.
Are replays safe?
Yes. Inserts are batched 1,000 rows per multi-VALUES statement. Transient errors (connection reset, deadlock) retry with backoff; permanent errors (auth, missing table) land in the dead-letter queue. INSERT IGNORE keyed on event_id makes replay a no-op for rows already inserted.