惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
J
Java Code Geeks
小众软件
小众软件
Jina AI
Jina AI
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Hugging Face - Blog
Hugging Face - Blog
Stack Overflow Blog
Stack Overflow Blog
Blog — PlanetScale
Blog — PlanetScale
C
Check Point Blog
人人都是产品经理
人人都是产品经理
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - Franky
Apple Machine Learning Research
Apple Machine Learning Research
G
Google Developers Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The GitHub Blog
The GitHub Blog
腾讯CDC
T
The Blog of Author Tim Ferriss
大猫的无限游戏
大猫的无限游戏
量子位
M
MIT News - Artificial intelligence
Last Week in AI
Last Week in AI
L
LangChain Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
PDF to Text Conversion with Rust on AWS Lambda
fayismahmood · 2026-05-19 · via DEV Community

A complete guide to building a serverless PDF conversion service using Rust, pdf_oxide, and cargo-lambda.

Demo: https://pdf-to-text-phi.vercel.app

Repo: https://github.com/fayismahmood/pdf-to-text

Prerequisites

You'll need Rust 1.70+ installed, AWS CLI configured with credentials, and basic familiarity with AWS Lambda concepts. For cargo-lambda installation, follow the official guide.

Your AWS IAM user also needs permissions for:

  • lambda:* (or the required Lambda deployment permissions)
  • iam:CreateRole
  • iam:AttachRolePolicy
  • iam:PassRole

Without these permissions, cargo lambda deploy may fail during the initial deployment when creating the Lambda execution role.
To install cargo-lambda, follow the official installation guide:

Installing cargo-lambda

cargo-lambda is the official Cargo subcommand for AWS Lambda functions.

macOS / Linux

curl -L https:// cargo-lambda.info/install.sh | sh

Enter fullscreen mode Exit fullscreen mode

Verify: cargo lambda --version

Project Setup

Create new project

cargo lambda new pdf-converter --http
cd pdf-converter

Enter fullscreen mode Exit fullscreen mode

This creates an HTTP-compatible Lambda project with API Gateway integration.

Update Cargo.toml

[package]
name = "pdf-converter"
version = "0.1.0"
edition = "2021"

[dependencies]
lambda_http = "1.0"
pdf_oxide = "0.3"
tokio = { version = "1", features = ["macros"] }

Enter fullscreen mode Exit fullscreen mode

Code Implementation

src/http_handler.rs

use lambda_http::{Body, Error, Request, RequestExt, Response};
use pdf_oxide::{PdfDocument, converters::ConversionOptions};

pub(crate) enum FileType {
    Html,
    Text,
    Markdown,
}

impl FileType {
    fn from_str(s: &str) -> Option<Self> {
        match s.to_lowercase().as_str() {
            "html" => Some(FileType::Html),
            "text" => Some(FileType::Text),
            "markdown" => Some(FileType::Markdown),
            _ => None,
        }
    }
}

pub(crate) async fn function_handler(event: Request) -> Result<Response<Body>, Error> {
    let file_type = event
        .query_string_parameters_ref()
        .and_then(|params| params.first("file_type"))
        .unwrap_or("text");

    let file_type = FileType::from_str(file_type).unwrap_or(FileType::Text);

    let body = event.body().to_vec();
    let pdf_data = PdfDocument::from_bytes(body)?;

    let options = ConversionOptions::default();
    let page_count = pdf_data.page_count()?;
    let mut result = String::new();

    for i in 0..page_count {
        let page_content = match file_type {
            FileType::Html => pdf_data.to_html(i, &options)?,
            FileType::Text => pdf_data.to_plain_text(i, &options)?,
            FileType::Markdown => pdf_data.to_markdown(i, &options)?,
        };
        result.push_str(&page_content);
    }

    let content_type = match file_type {
        FileType::Html => "text/html",
        FileType::Text => "text/plain",
        FileType::Markdown => "text/markdown",
    };

    let resp = Response::builder()
        .status(200)
        .header("content-type", content_type)
        .body(result.into())
        .map_err(Box::new)?;
    Ok(resp)
}

Enter fullscreen mode Exit fullscreen mode

Local Testing

Start the local server

cargo lambda watch

Enter fullscreen mode Exit fullscreen mode

Send a PDF via curl

curl -X POST 'http://localhost:9000/function/function_handler?file_type=markdown' \
  -H 'Content-Type: application/pdf' \
  --data-binary @document.pdf

Enter fullscreen mode Exit fullscreen mode

Deployment

Build for production

cargo lambda build --release --arm64

Enter fullscreen mode Exit fullscreen mode

The --arm64 flag targets AWS Graviton processors for better cost/performance.

Deploy to AWS

cargo lambda deploy

Enter fullscreen mode Exit fullscreen mode

The first deployment will create an IAM role automatically. Subsequent deployments will reuse it.

Via AWS CLI

# Package the function
cargo lambda build --release

# Deploy
aws lambda deploy

Enter fullscreen mode Exit fullscreen mode

Performance Benchmarks

pdf_oxide Performance

pdf_oxide is one of the fastest PDF libraries available, with benchmark results on 3,830 real-world PDFs:

Python PDF Libraries Comparison

Library Mean Time Pass Rate License
pdf_oxide 0.8ms 100% MIT
PyMuPDF 4.6ms 99.3% AGPL-3.0
pypdfium2 4.1ms 99.2% Apache-2.0
pdfminer 16.8ms 98.8% MIT
pdfplumber 23.2ms 98.8% MIT

Rust PDF Libraries Comparison

Library Mean Time Pass Rate
pdf_oxide 0.8ms 100%
unfpdf 2.8ms 95.1%
pdf_extract 4.08ms 91.5%
oxidize_pdf 13.5ms 99.1%

pdf_oxide is 5× faster than pdf_extract and 17× faster than oxidize_pdf in Rust.

AWS Lambda Cold Start

Rust's minimal runtime and compiled binary size result in extremely fast cold starts:

Runtime Cold Start (typical)
Rust (provided.al2023) ~50-100ms
Node.js ~100-200ms
Python ~100-300ms
Java ~500-2000ms

Memory Usage

With pdf_oxide's efficient design, memory usage stays low:

PDF Size Peak Memory
100KB ~5MB
1MB ~20MB
10MB ~100MB

API Usage

Request

POST /function/function_handler?file_type={html|text|markdown}
Content-Type: application/pdf

<binary PDF data>

Enter fullscreen mode Exit fullscreen mode

Response

Returns the converted content with appropriate content-type header.

Example with AWS CLI

aws lambda invoke \
  --function-name pdf-converter \
  --payload '{"file_type": "markdown"}' \
  --cli-binary-format raw-in-base64-out \
  response.json

Enter fullscreen mode Exit fullscreen mode

Further Reading