Skip to content

GitHub Pages Limitations: When Is It NOT the Right Choice?

Problem

I deployed my side project to GitHub Pages. It was a simple portfolio site, worked great. Then I tried to add user authentication and a contact form that actually sends emails. That’s when everything broke.

My PHP contact form returned plain text instead of executing. My Node.js API endpoints returned 404 errors. And when I tried to set up a database for user sessions, I realized there was nowhere to connect it.

Here’s what I tried:

contact.php
<?php
// This DOES NOT WORK on GitHub Pages
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
mail('[email protected]', 'Contact Form', $message);
echo "Message sent!";
?>

The result? GitHub Pages served this file as plain text, revealing my email address to anyone who viewed the source. No execution. No email sent. Just a security problem.

What happened?

I searched Reddit and found developers making the same mistake I did. They assumed GitHub Pages was “free web hosting” without understanding what “static hosting” actually means.

The key insight from the discussion: GitHub Pages serves only files. It doesn’t run anything.

I went to GitHub’s official documentation and found the hard limits:

Official GitHub Pages Limits
| Limit | Value |
|---------------------------|-----------------|
| Source repository size | 1 GB recommended|
| Published site size | 1 GB maximum |
| Bandwidth | 100 GB/month |
| Build timeout | 10 minutes |
| Builds per hour | 10 (soft limit) |

The bandwidth limit caught my attention. 100GB per month sounds like a lot until you host images. A site with 10MB of images per page and 10,000 monthly visitors hits that limit fast.

Why this matters

The problem isn’t just about what doesn’t work. It’s about understanding the fundamental architecture:

GitHub Pages Architecture
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Source │────▶│ Build │────▶│ Static │
│ Files │ │ Process │ │ Output │
└─────────────┘ └─────────────┘ └─────────────┘
┌─────────────┐
│ CDN │
│ Delivery │
└─────────────┘

There’s no server. No runtime. No database connection. Just files pushed through a build process and served from a CDN.

I tested this with a simple API attempt:

api.js
// This file will NEVER execute on GitHub Pages
export async function handler(event) {
return {
statusCode: 200,
body: JSON.stringify({ message: "Hello" })
}
}

When I pushed this to GitHub Pages, the file was served as a download. Not executed. Not proxied. Just delivered as a static file.

The hard limits

1. No Server-Side Processing

This is the fundamental limitation. GitHub Pages cannot execute any server-side code:

Server-Side Technologies That DON'T Work
| Technology | Result |
|------------|----------------------------------|
| PHP | Served as plain text |
| Node.js | No runtime available |
| Python | No interpreter |
| Ruby | No Ruby runtime |
| Java/JSP | No application server |
| .NET | No CLR runtime |

I tried to work around this with a form submission:

contact.html
<form action="process.php" method="POST">
<input type="email" name="email" required>
<textarea name="message" required></textarea>
<button type="submit">Send</button>
</form>

When I submitted the form, I got a 404 error. The PHP file doesn’t exist as an executable endpoint - it’s just a text file in the repository.

2. No Database Support

I wanted to store user preferences. I tried to set up a simple database connection:

db.py
# This will NEVER work on GitHub Pages
import psycopg2
conn = psycopg2.connect(
host="localhost",
database="myapp",
user="postgres",
password="secret"
)
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")

This code has nowhere to run. Even if it could run, there’s no database server to connect to. GitHub Pages provides zero database infrastructure.

3. Bandwidth Constraints

The 100GB monthly bandwidth limit is a “soft” limit, meaning GitHub contacts you before disabling your site. But that’s not comforting when your site suddenly stops loading.

I calculated my bandwidth usage:

Bandwidth Calculation
Site with heavy images:
- Average page size: 2MB
- Daily visitors: 1,000
- Pages per visitor: 3
Daily bandwidth: 1,000 x 3 x 2MB = 6GB
Monthly bandwidth: 6GB x 30 = 180GB
Result: OVER LIMIT (180GB > 100GB)

A simple portfolio with high-resolution images can hit this limit quickly.

4. Terms of Service Restrictions

GitHub explicitly prohibits certain use cases:

Prohibited Uses (from GitHub ToS)
- E-commerce sites processing transactions
- SaaS applications
- Sending passwords or credit card numbers
- Commercial web hosting
- High-traffic commercial sites

I didn’t realize this when I tried to build a small e-commerce prototype. The ToS violation could have resulted in my site being taken down.

When NOT to use GitHub Pages

After my failed attempts, I created a decision matrix:

Decision Matrix: GitHub Pages vs Alternatives
| Your Need | GitHub Pages? | Better Alternative |
|-----------------------------|---------------|--------------------------|
| User login/authentication | NO | Vercel, Netlify, VPS |
| Process payments | NO | Stripe + static frontend |
| Real-time features | NO | Firebase + static frontend|
| Database queries | NO | VPS, cloud hosting |
| >100GB monthly bandwidth | NO | Cloudflare Pages, VPS |
| E-commerce checkout | NO | Shopify, WooCommerce |
| SaaS application | NO | VPS, PaaS |
| Simple portfolio/blog | YES | - |
| Documentation site | YES | - |
| Project landing page | YES | - |

The pattern is clear: if you need any backend logic, GitHub Pages is the wrong choice.

Workarounds that actually work

I found legitimate workarounds for some limitations:

Client-Side Forms

Instead of server-side form processing, I used Formspree:

contact.html
<form action="https://formspree.io/f/YOUR_ID" method="POST">
<input type="email" name="email" required>
<textarea name="message" required></textarea>
<button type="submit">Send</button>
</form>

Formspree receives the form submission and emails it to me. No server required on my end.

Third-Party Authentication

For user authentication, I use Firebase with client-side JavaScript:

auth.js
import { initializeApp } from 'firebase/app'
import { getAuth, signInWithPopup, GoogleAuthProvider } from 'firebase/auth'
const app = initializeApp(firebaseConfig)
const auth = getAuth(app)
const provider = new GoogleAuthProvider()
// Client-side authentication
signInWithPopup(auth, provider)
.then((result) => {
const user = result.user
console.log('Signed in:', user.email)
})

This works entirely in the browser. GitHub Pages serves the JavaScript, Firebase handles the auth.

External API Integration

For database-like functionality, I use Supabase:

data.js
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(SUPABASE_URL, SUPABASE_KEY)
// Client-side database queries
const { data, error } = await supabase
.from('posts')
.select('*')
.order('created_at', { ascending: false })

Again, everything runs in the browser. GitHub Pages just serves the static files.

The reason

GitHub Pages is designed for documentation and project sites, not applications. The architecture is intentionally simple:

  1. Static file serving: Files are served exactly as they are
  2. CDN distribution: Content is cached at edge locations
  3. Jekyll processing: Optional build-time transformation
  4. No runtime: Zero server-side execution capability

This design makes GitHub Pages fast, reliable, and free. But it also creates hard boundaries that cannot be crossed.

The key point I learned: Static hosting is not limited hosting. It’s fundamentally different hosting.

Summary

In this post, I showed when GitHub Pages is the wrong choice and why. The key limitations are:

  • No server-side processing (PHP, Node.js, Python, etc.)
  • No database support
  • 100GB/month bandwidth soft limit
  • ToS prohibits e-commerce and SaaS

Use GitHub Pages for: portfolios, documentation, project landing pages, blogs.

Do NOT use GitHub Pages for: user authentication with sensitive data, payment processing, real-time features, anything requiring a database, high-bandwidth media sites.

If you need backend functionality, the alternatives are clear: Vercel, Netlify, or a VPS. GitHub Pages serves a specific purpose, and understanding its limits prevents the frustration I experienced.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments