---
description: This example provides a step-by-step guide on using event notifications to capture and store R2 upload logs in a separate bucket.
title: Log and store upload events in R2 with event notifications
image: https://developers.cloudflare.com/og-docs.png
---

[Skip to content](#main-content)

> Documentation Index  
> Fetch the complete documentation index at: https://developers.cloudflare.com/r2/llms.txt  
> Use this file to discover all available pages before exploring further.

# Log and store upload events in R2 with event notifications

Last updated Aug 24, 2026|Copy as Markdown|[View as Markdown](https://e8aee267.previews.developers.cloudflare.com/r2/tutorials/upload-logs-event-notifications/index.md)|[Agent setup](https://e8aee267.previews.developers.cloudflare.com/agent-setup/)

This example provides a step-by-step guide on using [event notifications](https://e8aee267.previews.developers.cloudflare.com/r2/buckets/event-notifications/) to capture and store R2 upload logs in a separate bucket.

![Push-Based R2 Event Notifications](https://e8aee267.previews.developers.cloudflare.com/cdn-cgi/image/onerror=redirect,width=912,height=472,format=svg/_astro/pushed-based-event-notification.NdMYExDK.svg) 

## 1\. Install Wrangler

To begin, refer to [Install/Update Wrangler](https://e8aee267.previews.developers.cloudflare.com/workers/wrangler/install-and-update/#install-wrangler) to install Wrangler, the Cloudflare Developer Platform CLI.

## 2\. Create R2 buckets

You will need to create two R2 buckets:

* `example-upload-bucket`: When new objects are uploaded to this bucket, your [consumer Worker](https://e8aee267.previews.developers.cloudflare.com/queues/get-started/#4-create-your-consumer-worker) will write logs.
* `example-log-sink-bucket`: Upload logs from `example-upload-bucket` will be written to this bucket.

To create the buckets, run the following Wrangler commands:

```sh
npx wrangler r2 bucket create example-upload-bucket
npx wrangler r2 bucket create example-log-sink-bucket
```

## 3\. Create a queue

Event notifications capture changes to data in `example-upload-bucket`. You will need to create a new queue to receive notifications:

```sh
npx wrangler queues create example-event-notification-queue
```

## 4\. Create a Worker

Before you enable event notifications for `example-upload-bucket`, you need to create a [consumer Worker](https://e8aee267.previews.developers.cloudflare.com/queues/reference/how-queues-works/#create-a-consumer-worker) to receive the notifications.

Create a new Worker with C3 (`create-cloudflare` CLI). [C3](https://e8aee267.previews.developers.cloudflare.com/pages/get-started/c3/) is a command-line tool designed to help you set up and deploy new applications, including Workers, to Cloudflare.

npmyarnpnpm

```
npm create cloudflare@latest -- consumer-worker
```

```
yarn create cloudflare consumer-worker
```

```
pnpm create cloudflare@latest consumer-worker
```

For setup, select the following options:

* For _What would you like to start with?_, choose `Hello World example`.
* For _Which template would you like to use?_, choose `Worker only`.
* For _Which language do you want to use?_, choose `TypeScript`.
* For _Do you want to use git for version control?_, choose `Yes`.
* For _Do you want to deploy your application?_, choose `No` (we will be making some changes before deploying).

Then, move into your newly created directory:

```sh
cd consumer-worker
```

## 5\. Configure your Worker

In your Worker project's \[[Wrangler configuration file](https://e8aee267.previews.developers.cloudflare.com/workers/wrangler/configuration/)\](/workers/wrangler/configuration/), add a [queue consumer](https://e8aee267.previews.developers.cloudflare.com/workers/wrangler/configuration/#queues) and [R2 bucket binding](https://e8aee267.previews.developers.cloudflare.com/workers/wrangler/configuration/#r2-buckets). The queues consumer bindings will register your Worker as a consumer of your future event notifications and the R2 bucket bindings will allow your Worker to access your R2 bucket.

```jsonc
{
	"$schema": "./node_modules/wrangler/config-schema.json",
	"name": "event-notification-writer",
	"main": "src/index.ts",
	// Set this to today's date
	"compatibility_date": "2026-08-24",
	"compatibility_flags": [
		"nodejs_compat"
	],
	"queues": {
		"consumers": [
			{
				"queue": "example-event-notification-queue",
				"max_batch_size": 100,
				"max_batch_timeout": 5
			}
		]
	},
	"r2_buckets": [
		{
			"binding": "LOG_SINK",
			"bucket_name": "example-log-sink-bucket"
		}
	]
}
```

```toml
"$schema" = "./node_modules/wrangler/config-schema.json"
name = "event-notification-writer"
main = "src/index.ts"
# Set this to today's date
compatibility_date = "2026-08-24"
compatibility_flags = [ "nodejs_compat" ]

[[queues.consumers]]
queue = "example-event-notification-queue"
max_batch_size = 100
max_batch_timeout = 5

[[r2_buckets]]
binding = "LOG_SINK"
bucket_name = "example-log-sink-bucket"
```

## 6\. Write event notification messages to R2

Add a [queue handler](https://e8aee267.previews.developers.cloudflare.com/queues/configuration/javascript-apis/#consumer) to `src/index.ts` to handle writing batches of notifications to our log sink bucket (you do not need a [fetch handler](https://e8aee267.previews.developers.cloudflare.com/workers/runtime-apis/handlers/fetch/)):

```ts
export interface Env {
	LOG_SINK: R2Bucket;
}

export default {
	async queue(batch, env): Promise<void> {
		const batchId = new Date().toISOString().replace(/[:.]/g, "-");
		const fileName = `upload-logs-${batchId}.json`;

		// Serialize the entire batch of messages to JSON
		const fileContent = new TextEncoder().encode(
			JSON.stringify(batch.messages),
		);

		// Write the batch of messages to R2
		await env.LOG_SINK.put(fileName, fileContent, {
			httpMetadata: {
				contentType: "application/json",
			},
		});
	},
} satisfies ExportedHandler<Env>;
```

## 7\. Deploy your Worker

To deploy your consumer Worker, run the [wrangler deploy](https://e8aee267.previews.developers.cloudflare.com/workers/wrangler/commands/general/#deploy) command:

```sh
npx wrangler deploy
```

## 8\. Enable event notifications

Now that you have your consumer Worker ready to handle incoming event notification messages, you need to enable event notifications with the [wrangler r2 bucket notification create command](https://e8aee267.previews.developers.cloudflare.com/workers/wrangler/commands/r2/#r2-bucket-notification-create) for `example-upload-bucket`:

```sh
npx wrangler r2 bucket notification create example-upload-bucket --event-type object-create --queue example-event-notification-queue
```

## 9\. Test

Now you can test the full end-to-end flow by uploading an object to `example-upload-bucket` in the Cloudflare dashboard. After you have uploaded an object, logs will appear in `example-log-sink-bucket` in a few seconds.

Was this helpful?

YesNo

## On this page

[![](https://e8aee267.previews.developers.cloudflare.com/_astro/logo.te5VL_aD.svg)Docs](https://e8aee267.previews.developers.cloudflare.com/)

```json
{"@context":"https://schema.org","@type":"TechArticle","@id":"https://developers.cloudflare.com/r2/tutorials/upload-logs-event-notifications/#page","headline":"Log and store upload events in R2 with event notifications · Cloudflare R2 docs","description":"This example provides a step-by-step guide on using event notifications to capture and store R2 upload logs in a separate bucket.","url":"https://developers.cloudflare.com/r2/tutorials/upload-logs-event-notifications/","inLanguage":"en","image":"https://developers.cloudflare.com/og-docs.png","dateModified":"2026-08-24","publisher":{"@type":"Organization","name":"Cloudflare","url":"https://www.cloudflare.com/"},"isPartOf":{"@type":"WebSite","@id":"https://developers.cloudflare.com/#website","name":"Cloudflare Docs","url":"https://developers.cloudflare.com/"},"keywords":["TypeScript"]}
```
