tutorial

Monitoring Self-Hosted Papermark with Vigilmon

Papermark is the self-hosted DocSend alternative for secure document sharing — but if the Next.js server, PDF pipeline, or S3 storage goes down, your prospects can't open your decks. Here's how to monitor every layer of Papermark with Vigilmon.

Papermark is the open-source DocSend alternative that lets you share pitch decks, legal documents, and sales proposals with per-viewer link tracking and analytics. When a prospect clicks your link, they expect the document to load instantly. If the Next.js server is overloaded, the PDF renderer has crashed, or S3 storage is inaccessible, that link returns an error — and you won't know until you check the link yourself. Vigilmon monitors every layer of Papermark so you can confidently share documents knowing that alerts will reach you before your prospects do.

What You'll Set Up

  • HTTP uptime monitor for the Papermark web server (port 3000)
  • Document upload and storage service monitor (S3/local)
  • PDF rendering and processing pipeline heartbeat
  • Link tracking and analytics service health check
  • PostgreSQL database monitor via TCP
  • Email notification delivery heartbeat
  • Viewer session tracking service monitor
  • Custom domain routing health check
  • Document watermarking pipeline heartbeat

Prerequisites

  • Papermark installed and running (Docker or Vercel/self-hosted)
  • Papermark accessible at http://your-server:3000 or behind a reverse proxy
  • PostgreSQL database running and accessible
  • A free Vigilmon account

Step 1: Monitor the Papermark Web Server

Papermark is a Next.js application that serves both the document management UI and the public document viewer. Both run on the same Next.js process — if it crashes, neither senders nor recipients can access documents.

  1. Log in to vigilmon.online and click Add Monitor.
  2. Set Type to HTTP / HTTPS.
  3. Enter your Papermark URL: https://papermark.yourdomain.com (or http://your-server:3000).
  4. Set Check interval to 1 minute.
  5. Set Expected HTTP status to 200.
  6. Enable Monitor SSL certificate with a 21-day expiry alert if you use HTTPS.
  7. Click Save.

Papermark's root path redirects to the login page — check that your Vigilmon monitor follows redirects. Under the monitor settings, ensure Follow redirects is enabled (it is by default).

For a more direct health signal, add a second monitor for the API route:

  1. Click Add MonitorHTTP / HTTPS.
  2. Set URL to https://papermark.yourdomain.com/api/health (if available in your version).
  3. Set Expected HTTP status to 200.
  4. Set Check interval to 1 minute.
  5. Click Save.

Step 2: Monitor Document Upload and Storage

Papermark stores uploaded PDFs and document assets in either a local filesystem path or an S3-compatible bucket (AWS S3, MinIO, Cloudflare R2, Supabase Storage). If storage becomes unavailable, document uploads fail and existing documents may become inaccessible to viewers.

AWS S3 or Compatible (Recommended for Production)

Monitor the storage service's health endpoint:

MinIO:

  1. Click Add MonitorHTTP / HTTPS.
  2. Set URL to http://minio-host:9000/minio/health/live.
  3. Set Expected HTTP status to 200.
  4. Click Save.

For AWS S3 or R2, you can't probe the bucket directly without authentication, so monitor connectivity via a cron heartbeat on the Papermark host:

#!/bin/bash
# papermark-s3-health.sh
# Check S3 bucket is accessible using the same credentials Papermark uses

aws s3 ls "s3://${PAPERMARK_BUCKET_NAME}/" \
  --region "${AWS_REGION}" \
  --max-items 1 > /dev/null 2>&1 && \
  curl -s https://vigilmon.online/heartbeat/S3_HEARTBEAT_ID

Schedule every 5 minutes with a matching Vigilmon cron heartbeat.

Local Storage

Monitor disk space and write access:

#!/bin/bash
STORAGE_DIR="/path/to/papermark/uploads"
DISK_USAGE=$(df "$STORAGE_DIR" | awk 'NR==2 {print $5}' | tr -d '%')

if [ "${DISK_USAGE:-100}" -lt 85 ] && touch "$STORAGE_DIR/.healthcheck" 2>/dev/null; then
  rm -f "$STORAGE_DIR/.healthcheck"
  curl -s https://vigilmon.online/heartbeat/STORAGE_HEARTBEAT_ID
fi

Step 3: Monitor the PDF Rendering Pipeline

Papermark processes uploaded PDFs to generate per-page images for the in-browser viewer (so viewers see pages without downloading the full PDF). This rendering pipeline typically uses a headless Chrome/Puppeteer instance or a server-side PDF library. If it crashes, newly uploaded documents show blank pages for viewers.

Add a heartbeat that verifies end-to-end document processing:

#!/bin/bash
# papermark-pdf-health.sh
# Upload a minimal test PDF and verify it processes successfully

# Check for recently processed documents in the database
PROCESSED_COUNT=$(psql -U papermark -d papermark -t -c \
  "SELECT COUNT(*) FROM documents 
   WHERE status = 'processed' 
   AND created_at > NOW() - INTERVAL '1 hour';" 2>/dev/null | tr -d ' ')

# On an active instance, there should be recent processed documents
# On a low-traffic instance, check that the processing queue is not backed up
PENDING_COUNT=$(psql -U papermark -d papermark -t -c \
  "SELECT COUNT(*) FROM documents WHERE status = 'processing';" \
  2>/dev/null | tr -d ' ')

# Alert if more than 5 documents have been stuck in "processing" for over 10 minutes
STUCK_COUNT=$(psql -U papermark -d papermark -t -c \
  "SELECT COUNT(*) FROM documents 
   WHERE status = 'processing' 
   AND updated_at < NOW() - INTERVAL '10 minutes';" 2>/dev/null | tr -d ' ')

if [ "${STUCK_COUNT:-0}" -lt 5 ]; then
  curl -s https://vigilmon.online/heartbeat/PDF_PIPELINE_HEARTBEAT_ID
fi

Schedule every 5 minutes and set the Vigilmon heartbeat interval to 5 minutes.


Step 4: Monitor Link Tracking and Analytics

Papermark's link tracking is its core differentiator — per-viewer analytics, page-by-page time tracking, and visit notifications. This is handled by API routes that write view events to PostgreSQL in real time. If analytics writes fail, senders lose visibility into who opened their documents.

Monitor the analytics ingestion endpoint:

  1. Click Add MonitorHTTP / HTTPS.
  2. Set URL to https://papermark.yourdomain.com/api/links.
  3. Set Expected HTTP status to 200 or 401 (the endpoint requires auth, so a 401 means it's alive).
  4. Set Check interval to 2 minutes.
  5. Click Save.

For deeper tracking health, add a database write check:

#!/bin/bash
# Verify view events are being written (on an active instance)
RECENT_VIEWS=$(psql -U papermark -d papermark -t -c \
  "SELECT COUNT(*) FROM views 
   WHERE created_at > NOW() - INTERVAL '24 hours';" 2>/dev/null | tr -d ' ')

# If the database is up and queryable, this succeeds
if psql -U papermark -d papermark -c "SELECT 1;" > /dev/null 2>&1; then
  curl -s https://vigilmon.online/heartbeat/ANALYTICS_HEARTBEAT_ID
fi

Step 5: Monitor PostgreSQL

All Papermark data — documents, links, teams, views, and analytics — is stored in PostgreSQL via Prisma ORM. A database failure immediately breaks every function of the application.

  1. Click Add MonitorTCP Port.
  2. Set Host to your PostgreSQL server.
  3. Set Port to 5432.
  4. Set Check interval to 1 minute.
  5. Click Save.

Add a connection-level heartbeat for deeper coverage:

# Add to crontab
* * * * * pg_isready -h localhost -U papermark -d papermark && \
  curl -s https://vigilmon.online/heartbeat/POSTGRES_HEARTBEAT_ID

Also verify Prisma can connect by checking the Papermark API startup log on the host:

# Monitor for Prisma connection errors
journalctl -u papermark --since "1 minute ago" 2>/dev/null | \
  grep -q "PrismaClientInitializationError\|Can't reach database" && \
  echo "PRISMA CONNECTION ERROR - DO NOT PING HEARTBEAT"

Step 6: Monitor Email Notification Delivery

Papermark sends email notifications when a viewer opens a shared link (if the sender has enabled visit notifications). These emails are sent via a configured SMTP server or transactional email provider (Resend, SendGrid, Postmark). If email delivery fails, senders miss real-time open notifications.

Add a cron heartbeat that verifies your email provider's API is reachable:

For Resend:

#!/bin/bash
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
  -H "Authorization: Bearer ${RESEND_API_KEY}" \
  https://api.resend.com/emails)

# 200 = list returned, 401 = wrong key (but API is up)
if [ "$HTTP_STATUS" -eq 200 ] || [ "$HTTP_STATUS" -eq 401 ]; then
  curl -s https://vigilmon.online/heartbeat/EMAIL_HEARTBEAT_ID
fi

For SMTP:

#!/bin/bash
# Check SMTP port is open
nc -z -w 5 "${SMTP_HOST}" "${SMTP_PORT:-587}" && \
  curl -s https://vigilmon.online/heartbeat/EMAIL_HEARTBEAT_ID

Schedule every 5 minutes.


Step 7: Monitor Viewer Session Tracking

Papermark tracks each viewer's session to enforce one-time access links, password protection, and email verification gates. Sessions are managed via JWT tokens and stored in the database. If session tracking breaks, password-protected documents become either inaccessible or unprotected.

Monitor the viewer auth endpoint:

  1. Click Add MonitorHTTP / HTTPS.
  2. Set URL to https://papermark.yourdomain.com/api/auth/session.
  3. Set Expected HTTP status to 200 (returns null session for unauthenticated requests).
  4. Set Check interval to 2 minutes.
  5. Click Save.
# Verify session endpoint responds correctly
curl https://papermark.yourdomain.com/api/auth/session
# {"user":null} or {"user":{...}} - both are healthy responses

Step 8: Monitor Custom Domain Routing

Papermark supports custom domains for document viewer links (e.g., docs.yourcompany.com instead of papermark.yourdomain.com). Custom domains require DNS CNAME records and TLS certificates that can expire or fail to renew.

For each custom domain configured in Papermark:

  1. Click Add MonitorHTTP / HTTPS.
  2. Set URL to https://docs.yourcompany.com (your custom domain).
  3. Set Expected HTTP status to 200 or 301 (a redirect to the login page is fine).
  4. Enable Monitor SSL certificate with a 21-day expiry alert.
  5. Set Check interval to 5 minutes.
  6. Click Save.

If you have multiple custom domains, add one monitor per domain. Custom domain TLS certificates are often managed separately from your main Papermark domain and are the most common source of silent failures.


Step 9: Monitor the Document Watermarking Pipeline

If you have enabled dynamic watermarking (embedding viewer email or IP address into the PDF at view time), the watermarking pipeline runs on every page load for protected documents. If it crashes, viewers either see unwatermarked documents or get an error.

Add a heartbeat that checks the watermarking service status:

#!/bin/bash
# Check for watermarking errors in recent Papermark logs
ERROR_COUNT=$(journalctl -u papermark --since "5 minutes ago" 2>/dev/null | \
  grep -c "watermark.*error\|PDFProcessingError\|canvas.*failed" || echo 0)

if [ "${ERROR_COUNT:-0}" -lt 3 ]; then
  curl -s https://vigilmon.online/heartbeat/WATERMARK_HEARTBEAT_ID
fi

If your Papermark version stores watermarking task status in the database:

STUCK_WATERMARKS=$(psql -U papermark -d papermark -t -c \
  "SELECT COUNT(*) FROM document_versions 
   WHERE watermark_status = 'processing' 
   AND updated_at < NOW() - INTERVAL '5 minutes';" 2>/dev/null | tr -d ' ')

if [ "${STUCK_WATERMARKS:-0}" -lt 3 ]; then
  curl -s https://vigilmon.online/heartbeat/WATERMARK_HEARTBEAT_ID
fi

Step 10: Configure Alert Channels and Response Time Alerts

  1. Go to Alert Channels in Vigilmon and connect Slack or email.
  2. Set Consecutive failures before alert to 1 for the PostgreSQL TCP monitor.
  3. Set it to 2 for the web server monitor to absorb brief restart events.

Enable response time alerts on the document viewer URL — this is the most user-facing part of Papermark and the first thing prospects notice:

  1. Open the Papermark web server monitor.
  2. Under Performance, enable Alert on slow response.
  3. Set Alert threshold to 3000ms (3 seconds) for the full page load.
  4. Click Save.

For the PDF viewer specifically, add a response time monitor on a known document link:

https://papermark.yourdomain.com/view/{a-test-document-id}

Set a 5 second alert threshold — PDF page rendering naturally takes longer than a standard page load.


Summary

| Monitor | Target | What It Catches | |---|---|---| | Web server | https://papermark.domain.com | Next.js crash, routing failure | | API health | /api/health | Next.js API routes not responding | | S3/storage heartbeat | S3 list or MinIO health | Document uploads and viewer assets failing | | PDF pipeline heartbeat | DB stuck-document count | Pages rendering blank for new uploads | | Analytics endpoint | /api/links | View tracking not recording | | PostgreSQL TCP | :5432 | Full application database down | | PostgreSQL heartbeat | pg_isready cron | Connection pool exhaustion | | Email heartbeat | SMTP or API cron | Open notifications not delivering | | Session endpoint | /api/auth/session | Auth broken, protected docs inaccessible | | Custom domain | Each custom domain URL | CNAME or TLS failure | | Watermark heartbeat | Log or DB cron | Watermarked PDFs failing to render | | Response time alert | Web UI + document viewer | Slow PDF rendering impacting viewer experience |

When a prospect clicks your Papermark link, the next few seconds determine whether they engage with your document or bounce. With Vigilmon monitoring every layer — from the Next.js process to the S3 bucket to the email delivery pipeline — you'll know before your prospect does when something goes wrong, and you can fix it before it costs you a deal.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →