October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
Active Storage

How to Save PDFs to Amazon S3 in Ruby

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a standalone Ruby script or service, use AWS SDK for Ruby v3 and upload the local PDF with an S3 object’s upload_file method. Set the object’s content type to application/pdf when it must be explicit, choose a key that will not overwrite another document unintentionally, and keep access private unless you have deliberately designed a sharing flow. In a Rails app that needs model attachments, Active Storage is usually the more natural route.

Choose direct S3 uploads or Rails Active Storage

The right path depends on whether you need S3 storage alone or Rails-managed attachment records and associations.

Approach Best fit What your application manages
AWS SDK for Ruby v3 A standalone Ruby program, background worker, or service that needs to write an object to S3. Your code chooses the bucket and key, performs the upload, and handles any application-level records or sharing workflow.
Rails Active Storage A Rails application that wants files attached to models through the framework’s storage abstraction. Active Storage integrates attachments with Rails; S3 is configured as a storage service rather than called directly for each attachment.

Both approaches can store a PDF in S3. They are not interchangeable at the application layer: direct SDK calls upload objects, while Active Storage also provides Rails attachment integration.

Upload a local PDF with AWS SDK for Ruby v3

Install the aws-sdk-s3 gem in your application, then configure AWS credentials and a region using the normal AWS SDK credential chain or your deployment’s credential mechanism. Do not put long-lived credentials directly in source code. The Ruby SDK repository identifies it as AWS’s official SDK and points to RubyGems as an installation channel.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall

Starting pattern for a file on disk

require "aws-sdk-s3"

s3 = Aws::S3::Resource.new(region: ENV.fetch("AWS_REGION"))
bucket = s3.bucket(ENV.fetch("S3_BUCKET"))
object = bucket.object("documents/report.pdf")

object.upload_file(
  "/path/to/report.pdf",
  content_type: "application/pdf"
)

puts "Uploaded to s3://#{bucket.name}/#{object.key}"

This is an illustrative v3 pattern, not a tested application. Confirm the exact options supported by the aws-sdk-s3 version installed in your project, especially if the gem is pinned to an older release. The v3 object API documents upload_file for files from disk. For a file-like body or data already in memory, use an upload operation that accepts a body, and set content_type if the PDF type needs to be controlled.

Choose an object key that will not collide

The key is the object’s name within the bucket; it is not necessarily a local filesystem path. The example’s fixed key, documents/report.pdf, is convenient for illustration but a later upload to that same key can replace the existing object. For user- or job-generated documents, build a key from an application identifier or another unique value, and retain that key wherever your application needs to find the upload. Do not use an untrusted filename as the entire key without considering path-like characters, collisions, and your application’s naming rules.

Make the PDF media type explicit

Use content_type: "application/pdf" when downstream consumers need the object identified as a PDF. A filename ending in .pdf and an object’s stored content type are separate details; if delivery behavior depends on the metadata, set it rather than relying on inference. The v3 object and bucket APIs document upload operations and content-type options.

Upload a PDF from an IO or data body

If the PDF is not a local file path—for example, it is already available as an IO object—use an operation that accepts a body. The v3 bucket API documents put_object with a file-like body and a content_type option.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
require "aws-sdk-s3"

s3 = Aws::S3::Resource.new(region: ENV.fetch("AWS_REGION"))
bucket = s3.bucket(ENV.fetch("S3_BUCKET"))

File.open("/path/to/report.pdf", "rb") do |file|
  bucket.put_object(
    key: "documents/report-#{ENV.fetch("JOB_ID")}.pdf",
    body: file,
    content_type: "application/pdf"
  )
end

Use binary mode ("rb") for a local PDF opened as a body. The example assumes JOB_ID is set and unique enough for your application; replace it with the identifier scheme you actually use. Check the installed v3 gem’s API documentation for the accepted options and behavior before adopting a snippet in production.

Use Active Storage in a Rails application

When a PDF belongs to a Rails model, Active Storage can manage the attachment integration and send the file to an S3 service. Follow the Rails Active Storage guide to configure the S3 service and credentials for your environment. Then declare the attachment on the model and attach an IO object with an explicit filename and content type where needed.

# app/models/report.rb
class Report < ApplicationRecord
  has_one_attached :pdf
end
# Example call in application code
report.pdf.attach(
  io: File.open("/path/to/report.pdf", "rb"),
  filename: "report.pdf",
  content_type: "application/pdf"
)

Ensure the opened file is closed in your application’s normal resource-management pattern. If the content type cannot be determined and none is supplied, Active Storage falls back to application/octet-stream; provide application/pdf when correct PDF metadata matters. A caller-supplied storage key should be unique for the upload. If you do not provide one, the Active Storage guide notes that it uses a random key.

Choose Active Storage when its attachment associations and abstraction are useful to the app. Choose direct SDK calls when you need to manage S3 object operations yourself and do not need Rails attachment integration for the file.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Plan for size, permissions, and access

Large files and multipart behavior

The v3 object documentation describes multipart upload behavior for upload_file when files meet or exceed its configured multipart threshold. Check the API reference and configuration for the v3 version in your application rather than assuming that every upload method handles large files in the same way.

Do not transfer a limit from an older SDK example to a v3 helper. The AWS SDK for Ruby v2 client reference describes its put_object file-streaming example as a single request and says that operation may not exceed 5 GB. That is a v2-specific statement; it does not establish the limit for v3’s upload_file helper.

Private by default; sharing is a separate decision

The v3 SDK reference describes objects as private by default. Keep that default unless your application has an intentional sharing design. A successful upload means the object was written; it does not prove that a browser or another user can read it. Upload permission and read or sharing authorization are separate concerns. Do not add a public-read ACL merely to test whether an upload worked.

Use a least-privilege role or credential

Configure the application’s AWS identity to perform the storage operations it actually needs, and protect that identity using your deployment’s credential mechanism. The available sources do not establish a complete IAM policy for every bucket layout or application; derive permissions from the actual operations, bucket, and key prefix your code uses rather than copying a broad policy without review.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot common upload problems

  • Missing region: the example uses ENV.fetch("AWS_REGION"), which raises if the variable is unset. Configure it for the target bucket’s region, or pass the intended region through your application configuration.
  • Missing bucket or key configuration: verify S3_BUCKET exists in the process environment and that the key is the intended object name, not an accidental local path.
  • Access denied: check which AWS identity the process is using and whether it has the required access for the bucket and key. Do not respond by making the object public; public read is a separate access policy.
  • Wrong or generic content type: set content_type: "application/pdf" on a direct upload. With Active Storage, supply the type when attaching if automatic detection does not identify it.
  • Unexpected overwrite: inspect the full key. Reusing a fixed key such as documents/report.pdf targets the same object name; use an application-appropriate unique key if each upload must remain distinct.
  • Old code or unsupported option: confirm the project uses AWS SDK for Ruby v3 and consult the documentation for its installed aws-sdk-s3 version. V2 and v3 references describe different APIs and must not be conflated.
  • Large upload behaves differently than expected: check the v3 upload_file multipart threshold and configuration for your installed version. Do not infer v3 helper limits from the v2 put_object example.

Or skip the browser setup

ScreenshotNeo is a website screenshot API, not an S3 uploader for an existing PDF. If your actual input is a webpage and the output you need is a screenshot or a PDF capture, one GET request can capture it; you would still use your own Ruby/AWS upload flow if you need to store that result in S3.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

See the ScreenshotNeo API documentation for request options. It accepts cookie or consent banners as a visitor and removes 60+ known consent platforms, newsletter popups, and chat widgets before capture; each of those steps can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for AI agents and MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots.

Sign up free for ScreenshotNeo to get 1,000 screenshots a month without a card.

Frequently Asked Questions

Does uploading a PDF to S3 make it publicly readable?

No. Upload success and read authorization are separate; an object can remain private after a successful upload.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Can I use Active Storage without calling the S3 SDK in every model?

Yes. Configure S3 as an Active Storage service and attach files through the Rails attachment interface.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Read next

Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.