Web seeds are HTTP/HTTPS servers that provide torrent content as a fallback or supplement to peer-to-peer downloads. They implement BEP19 and allow torrents to be downloaded even when no peers are available.
What are Web Seeds?
Web seeds provide several benefits:
- Guaranteed availability: Content remains accessible even with no peers
- Initial seeding: Helps bootstrap new torrents before peers arrive
- Performance: HTTP servers can often provide faster downloads than peers
- CDN integration: Use CDN infrastructure for torrent content
- Hybrid delivery: Combine P2P and HTTP for optimal performance
WebTorrent automatically manages web seed connections and switches between P2P and HTTP sources based on availability and performance.
Adding Web Seeds to Torrents
When creating a torrent, you can specify HTTP/HTTPS URLs as web seeds:
Basic Web Seed
import WebTorrent from 'webtorrent'
const client = new WebTorrent()
client.seed('/path/to/file.mp4', {
name: 'My Video',
urlList: [
'https://example.com/files/'
]
}, torrent => {
console.log('Torrent created with web seed')
console.log('Web seeds:', torrent.urlList)
})
Multiple Web Seeds
client.seed(files, {
name: 'My Files',
urlList: [
'https://cdn1.example.com/files/',
'https://cdn2.example.com/backup/',
'https://mirror.example.org/torrents/'
]
}, torrent => {
console.log('Added', torrent.urlList.length, 'web seeds')
})
The web seed URL should be a base path where files can be accessed:
// If your torrent contains: video.mp4
// Web seed URL: https://example.com/files/
// Full URL will be: https://example.com/files/video.mp4
client.seed('/path/to/video.mp4', {
urlList: ['https://example.com/files/']
})
For torrents with multiple files:
// Torrent contains:
// - folder/video1.mp4
// - folder/video2.mp4
// Web seed URL: https://example.com/content/
// Full URLs will be:
// - https://example.com/content/folder/video1.mp4
// - https://example.com/content/folder/video2.mp4
client.seed('/path/to/folder', {
urlList: ['https://example.com/content/']
})
Using Torrents with Web Seeds
When you download a torrent that has web seeds, WebTorrent automatically uses them:
const magnetURI = 'magnet:?xt=urn:btih:...&ws=https://example.com/files/'
client.add(magnetURI, torrent => {
console.log('Web seeds available:', torrent.urlList)
torrent.on('download', bytes => {
console.log('Downloaded from P2P or web seeds')
})
})
Checking Web Seed Status
client.add(magnetURI, torrent => {
torrent.on('wire', (wire, addr) => {
console.log('Connection type:', wire.type)
// Types: 'webrtc', 'tcpIncoming', 'tcpOutgoing', 'webSeed'
if (wire.type === 'webSeed') {
console.log('Connected to web seed')
}
})
})
Adding Web Seeds to Existing Torrents
You can add web seeds dynamically to torrents you’re downloading:
client.add(magnetURI, torrent => {
// Add a web seed after torrent is added
torrent.addWebSeed('https://backup-server.com/files/')
console.log('Web seeds:', torrent.urlList)
})
Add When No Peers Available
client.add(magnetURI, torrent => {
torrent.on('noPeers', announceType => {
console.log('No peers found, adding web seed')
torrent.addWebSeed('https://fallback-server.com/files/')
})
})
Configuring Web Seeds
Control web seed behavior with client options:
const client = new WebTorrent({
webSeeds: true, // Enable web seeds (default: true)
maxWebConns: 4 // Max simultaneous web seed connections per torrent
})
Or per-torrent:
client.add(magnetURI, {
maxWebConns: 8, // More connections = faster from web seeds
urlList: [ // Add additional web seeds
'https://my-server.com/files/'
]
}, torrent => {
console.log('Configured web seed connections')
})
Setting Up a Web Seed Server
Requirements
Host the files
Upload your torrent files to a web server with the same directory structure as the torrent.
Enable CORS (for browser clients)
Configure your server to send CORS headers:Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, HEAD, OPTIONS
Access-Control-Allow-Headers: Range
Support range requests
Enable HTTP range requests for seeking support:
Nginx Configuration
server {
listen 80;
server_name webseed.example.com;
location /files/ {
alias /var/www/torrents/;
# Enable CORS
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, HEAD, OPTIONS";
add_header Access-Control-Allow-Headers "Range";
# Support range requests
add_header Accept-Ranges bytes;
# Handle preflight requests
if ($request_method = OPTIONS) {
return 204;
}
}
}
Node.js Express Server
import express from 'express'
import cors from 'cors'
import path from 'path'
const app = express()
// Enable CORS for all origins
app.use(cors({
origin: '*',
methods: ['GET', 'HEAD', 'OPTIONS'],
allowedHeaders: ['Range']
}))
// Serve files with range request support
app.use('/files', express.static('/path/to/torrent/files', {
acceptRanges: true,
lastModified: true
}))
app.listen(3000, () => {
console.log('Web seed server listening on http://localhost:3000')
})
Python HTTP Server
from http.server import HTTPServer, SimpleHTTPRequestHandler
import os
class CORSRequestHandler(SimpleHTTPRequestHandler):
def end_headers(self):
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'GET, HEAD, OPTIONS')
self.send_header('Access-Control-Allow-Headers', 'Range')
self.send_header('Accept-Ranges', 'bytes')
super().end_headers()
def do_OPTIONS(self):
self.send_response(204)
self.end_headers()
os.chdir('/path/to/torrent/files')
server = HTTPServer(('', 8000), CORSRequestHandler)
print('Web seed server running on http://localhost:8000')
server.serve_forever()
Complete Web Seed Example
Create and seed a torrent with web seed support:
import WebTorrent from 'webtorrent'
import express from 'express'
import cors from 'cors'
import path from 'path'
const client = new WebTorrent()
// Set up web seed server
const app = express()
app.use(cors({ origin: '*' }))
app.use('/files', express.static('/path/to/files', { acceptRanges: true }))
const server = app.listen(3000, () => {
console.log('Web seed server: http://localhost:3000/files/')
// Create torrent with web seed
client.seed('/path/to/files/video.mp4', {
name: 'My Video',
urlList: ['http://localhost:3000/files/'],
announceList: [
['wss://tracker.btorrent.xyz'],
['wss://tracker.openwebtorrent.com']
]
}, torrent => {
console.log('\nTorrent created!')
console.log('Name:', torrent.name)
console.log('Info hash:', torrent.infoHash)
console.log('Web seeds:', torrent.urlList)
console.log('\nMagnet URI:')
console.log(torrent.magnetURI)
console.log('\nSeeding via P2P + web seed...')
// Monitor downloads from web seed
torrent.on('wire', (wire, addr) => {
if (wire.type === 'webSeed') {
console.log('Peer connected via web seed')
}
})
})
})
Browser Considerations
When using web seeds in the browser, the web seed server must have proper CORS headers. Without CORS, browsers will block the requests.
Testing CORS
// Test if web seed has proper CORS
fetch('https://example.com/files/test.mp4', {
method: 'HEAD',
headers: { 'Range': 'bytes=0-1' }
})
.then(response => {
console.log('CORS headers:', response.headers.get('access-control-allow-origin'))
console.log('Range support:', response.headers.get('accept-ranges'))
})
.catch(err => {
console.error('CORS error:', err)
})
Load Balancing
Use multiple web seeds for better performance:
client.seed(files, {
urlList: [
'https://cdn1.example.com/files/',
'https://cdn2.example.com/files/',
'https://cdn3.example.com/files/'
],
maxWebConns: 6 // 2 connections per web seed
})
Geographic Distribution
const webSeeds = [
'https://us-east.example.com/files/', // US East Coast
'https://us-west.example.com/files/', // US West Coast
'https://eu.example.com/files/', // Europe
'https://asia.example.com/files/' // Asia
]
client.seed(files, {
urlList: webSeeds,
maxWebConns: 8
})
Fallback Strategy
client.add(magnetURI, torrent => {
// Primary: Try P2P first
console.log('Trying P2P download...')
// After 30 seconds, add web seed if slow
setTimeout(() => {
if (torrent.downloadSpeed < 100000) { // Less than 100 KB/s
console.log('Slow P2P, adding web seed')
torrent.addWebSeed('https://backup.example.com/files/')
}
}, 30000)
})
Magnet URI with Web Seeds
Web seeds can be included in magnet URIs using the ws parameter:
const magnetURI = [
'magnet:?xt=urn:btih:08ada5a7a6183aae1e09d831df6748d566095a10',
'&dn=Sintel',
'&ws=https://webtorrent.io/torrents/',
'&ws=https://backup.example.com/files/',
'&tr=wss://tracker.btorrent.xyz'
].join('')
client.add(magnetURI, torrent => {
console.log('Web seeds from magnet:', torrent.urlList)
})
Monitoring Web Seed Usage
Track which sources are being used:
client.add(magnetURI, torrent => {
const stats = {
p2p: 0,
webSeed: 0
}
torrent.on('wire', (wire, addr) => {
wire.on('download', bytes => {
if (wire.type === 'webSeed') {
stats.webSeed += bytes
} else {
stats.p2p += bytes
}
})
})
setInterval(() => {
console.log('Downloaded from P2P:', (stats.p2p / 1024 / 1024).toFixed(2), 'MB')
console.log('Downloaded from web seeds:', (stats.webSeed / 1024 / 1024).toFixed(2), 'MB')
const total = stats.p2p + stats.webSeed
if (total > 0) {
console.log('Web seed ratio:', ((stats.webSeed / total) * 100).toFixed(1) + '%')
}
}, 5000)
})
Best Practices
Follow these best practices for optimal web seed performance:
- Use CDNs: Host web seeds on CDN infrastructure for global performance
- Multiple seeds: Provide 2-3 web seeds for redundancy
- Keep files synchronized: Ensure web seed content exactly matches torrent
- Monitor availability: Check that web seeds remain accessible
- Set proper headers: Always configure CORS and range request support
- Use HTTPS: Prefer HTTPS for security (required for some browsers)
- Rate limiting: Implement rate limiting on web seed servers if needed
Troubleshooting
Web Seeds Not Working
client.add(magnetURI, torrent => {
// Check if web seeds are configured
console.log('Web seeds:', torrent.urlList)
// Check if web seeds are enabled
console.log('Web seeds enabled:', client.enableWebSeeds)
// Monitor for errors
torrent.on('warning', err => {
console.warn('Warning:', err.message)
})
torrent.on('error', err => {
console.error('Error:', err.message)
})
})
CORS Issues
If web seeds aren’t working in the browser:
- Check browser console for CORS errors
- Verify server sends proper CORS headers
- Test with
curl or browser dev tools
- Ensure preflight OPTIONS requests are handled
File Not Found
If web seed returns 404:
- Verify file path matches torrent structure exactly
- Check URL encoding for special characters
- Ensure trailing slash on base URL
- Test direct URL access in browser