Object Storage & Blob StoragePresigned URLs & Access ControlHard⏱️ ~3 min

Implementation Patterns: Control Plane, Data Plane, and Post Upload Validation

A production presigned URL system cleanly separates control plane (URL generation and authorization) from data plane (actual bytes transfer), with careful orchestration for post upload validation, lifecycle management, and observability. The control plane is a stateless, horizontally scalable service that authenticates users, enforces business logic (ownership, quotas, file type and size policies), and generates presigned URLs. Deploy multi region for low latency: target p95 (95th percentile) under 50 milliseconds for URL generation. This service needs Identity and Access Management (IAM) or equivalent permissions only on the specific buckets and prefixes it serves, never global wildcards. For high security environments, rotate signing keys on a schedule (weekly or monthly) and monitor usage; any unsigned or expired key attempts indicate credential leakage. Capacity plan for query per second (QPS) spikes: single part uploads generate predictable load, but multipart uploads can create 100x to 1000x QPS bursts as clients request hundreds of part signatures per file. The data plane is the object storage or Content Delivery Network (CDN) layer handling actual uploads and downloads. Clients interact directly with storage using presigned URLs; your application servers never see the bytes. This offloads bandwidth, Central Processing Unit (CPU), and Network Address Translation (NAT) costs from your app tier. For large files, prefer multipart or resumable upload protocols: clients upload in parallel streams, and if a chunk fails, only that chunk retries with a fresh presigned URL rather than restarting the entire file. Set part sizes to balance parallelism and signing load: 32 MB to 64 MB is typical for multi gigabyte files, yielding 50 to 150 parts instead of 300 to 600 parts at 16 MB. Post upload validation and lifecycle are critical for security and cost. Do not trust that an uploaded object is what the user claimed or safe. After upload completes, the client notifies your backend with the object key and metadata. Your backend validates: object exists at expected key, size matches allowed range, hash matches if provided, and Content-Type is acceptable. For untrusted user content, trigger immediate virus scanning or content moderation via event driven workers (Lambda on S3 event, Cloud Function on Cloud Storage event). Apply lifecycle policies: transition to infrequent access or archive tiers after N days to reduce storage costs by 50% to 90%; set expiration for temporary uploads. Subscribe to storage events (object created, deleted) and reconcile against your database to detect orphaned or unexpected objects. Observability is essential for production operations. Track: presigned URL issuance latency (target p95 less than 50 milliseconds), issuance QPS and burst patterns, storage layer 4xx and 5xx rates by reason code (expired, signature mismatch, CORS, access denied), average and p99 upload sizes, multipart part counts, and time from upload to completion confirmation. Alert on anomalies: spike in expired or signature mismatch errors (suggests clock skew or header drift), uploads outside expected size or type (possible abuse), attempts outside allowed prefixes (confused deputy or security probing). Implement structured logging that redacts presigned URL query strings to prevent leakage via log aggregation systems.
💡 Key Takeaways
Stateless control plane for horizontal scale: URL generation is pure computation (HMAC signing), no database lookups required if you encode necessary scopes in signed tokens. Deploy multi region; use geo routing to nearest region for sub 30 millisecond p50 latency. Capacity plan for 10x to 20x average QPS to handle bursts, especially for multipart workloads.
Data plane offload: Every byte that goes client to storage directly instead of client to app to storage saves server bandwidth, Central Processing Unit (CPU), and Network Address Translation (NAT) charges. For 10 TB per month shifted, typical savings are $450 in NAT ($0.045 per GB) plus reduced autoscaling and egress costs, often totaling $1,000 to $3,000 monthly.
Event driven post upload validation: Never trust uploaded content. Subscribe to storage events (S3 Event Notifications, GCS Pub/Sub on object finalize) and trigger workers that validate size, type, hash, run virus or moderation scans, and update your database. Decouple validation from upload path to keep upload latency low; mark objects as pending until validated.
Lifecycle and cost management: Apply policies to transition uploads to cheaper tiers after N days (Infrequent Access saves approximately 50%, Archive approximately 80% versus standard). Set expiration on temporary or staging uploads. Monitor storage costs by bucket and prefix to detect runaway growth from orphaned objects or abuse.
Observability with redaction: Track URL generation latency, QPS, storage 4xx/5xx by error type, upload sizes and part counts, time to completion. Alert on spikes in expired or signature errors (clock skew), out of bounds sizes (quota bypass attempts), or unexpected prefixes (security probing). Critically, redact query strings from logs to prevent presigned URL leakage via log aggregation or third party services.
📌 Examples
Multi region control plane: Deploy URL signing service in us-east-1, eu-west-1, ap-southeast-1 behind geo routed DNS or Anycast load balancer. US clients hit us-east-1 (10 ms), EU clients hit eu-west-1 (15 ms), Asia clients hit ap-southeast-1 (12 ms). Each region autoscales independently; no shared state required since signing is stateless.
Event driven validation: S3 bucket emits event on PutObject to uploads/user-*/ prefix. SNS topic fans out to Lambda that checks: object size <100 MB, extension is .jpg or .png, hash matches client claim. If valid, Lambda writes record to DynamoDB with status=validated and sends push notification to user. If invalid, Lambda deletes object and logs incident.
Lifecycle cost savings: User uploads 1 TB of photos per month to standard storage at $0.023 per GB per month = $23.60. After 30 days, policy transitions to Infrequent Access at $0.0125 per GB per month; after 90 days, to Glacier at $0.004 per GB per month. Blended cost for 12 month lifecycle: approximately $10 per TB per month instead of $23.60, saving 58%.
← Back to Presigned URLs & Access Control Overview