File Storage

Object storage for uploads and documents

An object store attached to your project for user uploads, images, generated documents, and exports. Put and get files with a content type, list them by prefix, and serve them straight from a worker, with nothing to provision and no credentials to manage.

File Browser

Files

Everything your worker has stored, with its content type

KeyContent typeSize
uploads/user-123/avatar.pngimage/png48 KB
documents/invoices/inv-001.pdfapplication/pdf212 KB
exports/2026-10-01.csvtext/csv1.4 MB
config/app.jsonapplication/json312 B

List by Prefix

Group files under prefixes and list a folder in one call

src/index.ts
const { keys } = await env.FILES.list({
  prefix: "uploads/user-123/",
});
// ["uploads/user-123/avatar.png"]

Key Features

Put, Get, Delete, List

An S3-style API with content types, prefix listing, and binary or text payloads.

Organize by Prefix

Keep uploads/user-123/ and documents/invoices/ apart and list either in one call.

Serve From a Worker

Return file.body with its content type and cache headers directly from your fetch handler.

Browse in the Dashboard

Inspect what your app has stored without writing a script.

Upload and Serve

Store an upload with its content type, then serve it back with the right headers.

src/index.ts
export default {
  async fetch(request, env) {
    const url = new URL(request.url);

    if (request.method === "POST") {
      const key = `uploads/${Date.now()}`;
      await env.FILES.put(key, await request.arrayBuffer(), {
        contentType: request.headers.get("Content-Type") ?? "",
      });
      return Response.json({ key });
    }

    const file = await env.FILES.get(url.pathname.slice(1));
    if (!file) {
      return new Response("Not Found", { status: 404 });
    }
    return new Response(file.body, {
      headers: { "Content-Type": file.contentType },
    });
  },
} satisfies Ploy;

Ready to get started?

Deploy your first project in minutes with Ploy.