Server-Side vs Client-Side Components, SSR Best Practices and Secure Fetching with RLS
Understanding server-side and client-side components, secure data fetching with RLS and scaling SSR for large databases
Last updated: 8/15/2025
This guide explains the differences between server-side and client-side components, how to combine them effectively, how to secure client-side data fetching with Row-Level Security (RLS) and best practices for scaling Server-Side Rendering (SSR) with large databases.
1. Server-Side vs Client-Side Components
- Server-side components
- Run on the server before sending HTML to the browser.
- Ideal for SEO, secure data fetching and fast initial load times.
- Client-side components
- Run in the browser after the page loads.
- Handle interactivity and dynamic updates without a full page reload.
- Hybrid approach
- Modern frameworks (e.g., Next.js, Remix, Nuxt) combine both: server-side for initial rendering, client-side for user interaction.
2. Using Both in One Application
A common hybrid workflow:
- Server renders HTML with initial data.
- Browser hydrates interactive components with JavaScript.
- Client fetches additional data on demand (e.g., via
fetch()).
Example: A product page
- Server-side: fetches product details from a database and renders HTML.
- Client-side: handles "Add to Cart" clicks and updates the UI instantly without reloading.
3. Secure Client-Side Fetching with RLS
- Client-side fetching can be secure if API-level restrictions (such as Row-Level Security) strictly control data access.
- Risks:
- Requests are visible in browser DevTools.
- Never embed API keys in frontend code.
- Best practices:
- Require authentication for sensitive data.
- Apply RLS to scope queries to the authenticated user or tenant.
- Never rely on client-side filtering alone.
- Use short-lived tokens.
- Rate-limit and log all sensitive queries.
4. SSR with Large Databases
When scaling SSR for large datasets:
- Query only what you need — avoid
SELECT *. - Index properly — ensure indexes match your
WHERE+ORDER BY. - Use keyset/cursor pagination instead of OFFSET.
- Cache at multiple layers — Redis for query results, CDN/edge for public HTML.
- Read replicas for heavy read workloads; connection pooling to prevent overload.
- Partition large tables by date, tenant, or logical grouping.
- Stream SSR output to deliver above-the-fold content as soon as possible.
5. Three Common SSR Page Types
-
List pages (large collections)
- Composite index on filter/sort columns.
- Keyset paginate 20–50 items per request.
- Cache query results for 30–60s in Redis; edge-cache HTML if public.
-
Detail pages
- Fetch by primary key plus a small related set.
- Cache for 2–5 minutes with tag-based invalidation.
-
Personal dashboards
- Multiple small queries in parallel using a connection pool.
- Short-TTL Redis cache per widget; no public edge cache for private data.
6. Operational Playbook
- Connection pooling (e.g., pgBouncer, pgpool) to reuse DB connections.
- Read replicas for distributing read queries.
- Backpressure with query timeouts and circuit breakers.
- Online migrations for large tables to avoid downtime.
- Partitioning for very large tables.
- Data TTL policies to archive old rows and keep active datasets small.
7. Pitfalls to Avoid
- Offset pagination on huge tables.
- Rendering massive lists without proper pagination.
- Using
SELECT *in SSR. - Missing covering indexes for frequent queries.
- Publicly caching private or user-specific pages.
- Blocking SSR for slow assets instead of streaming.
8. Quick Checklist
- Queries return only the fields required for rendering.
- Keyset pagination for large lists.
- Indexes match
WHEREandORDER BYpatterns. - Read replicas and pooling in place.
- Redis cache with short TTL and stampede protection.
- SSR streams above-the-fold first.
- Least-privilege DB roles; secrets stored server-side only.
- Tenant scoping and optional RLS enforced.
- Monitoring for slow queries, cache hit rates and replica lag.
Related Topics
Learn more about security and data protection:
- Security Concepts - Core security principles and practices
- Row Level Security (RLS) Fundamentals - Understanding PostgreSQL's built-in security
- Multi-tenant Security Patterns - Implementing team and organisation-based data isolation
- Security Leak Prevention - Preventing API key leaks and setting up detection systems