Server‑Sent Events (SSE) vs WebSocket vs Polling: Detailed Comparison and SpringBoot Implementation
This article explains the lightweight Server‑Sent Events (SSE) approach for one‑way server push, compares its features, connection model, performance and use cases against WebSocket and traditional polling, and provides a SpringBoot example with code snippets for building an online‑user SSE endpoint.
In many real‑time projects the client only needs to receive messages from the server, making the full‑duplex WebSocket feature unnecessary; Server‑Sent Events (SSE) offers a simpler one‑way push solution.
Comparison Table
Feature
SSE (Server‑Sent Events)
Polling
WebSocket
Communication Direction
One‑way: server pushes to client
One‑way: client periodically requests
Two‑way: client ↔ server
Connection Type
Long‑living HTTP/1.1 or HTTP/2 connection
Short‑lived independent HTTP requests
Persistent TCP connection (WebSocket handshake)
Transport Protocol
HTTP/1.1 or HTTP/2
HTTP
TCP (via WebSocket protocol upgrade)
Browser Support
Widely supported (native HTML5)
All browsers support
Supported via WebSocket API
Message Frequency
Server can push anytime
Client decides polling interval
Real‑time bi‑directional
Server Overhead
Low – single long connection
High – new connection each poll
Higher – maintain TCP + heartbeat
Client Overhead
Low – just handle pushes
High – repeated requests
Medium – keep connection alive
Data Format
Text, JSON, etc.
Text, JSON, etc.
Any (binary, text, …)
Reconnection
Automatic on disconnect
Manual new request
Developer‑implemented
Typical Scenarios
Live data push, notifications, monitoring (one‑way)
Low‑frequency, non‑real‑time needs
Instant messaging, collaborative apps (two‑way)
Complexity
Simple, lightweight code
Simple but less performant
Complex – handshake, heart‑beat, reconnection logic
Real‑time
High – immediate server push
Low – depends on poll interval
High – bi‑directional
Firewall/Proxy Compatibility
High – standard HTTP
High – standard HTTP
May need special firewall rules for TCP
Bandwidth Consumption
Low – only data when needed
High – each poll consumes bandwidth
Low – long connection, data on demand
Why abandon WebSocket for simple push? WebSocket requires manual token handling during handshake, extra code for connection management, reconnection, and periodic message sending, which is overkill when only server‑to‑client notifications are needed.
Implementation Steps (SpringBoot)
1. Configure a custom AsyncTaskExecutor to avoid production warnings:
@Configuration
@Slf4j
public class WebMvcConfig implements WebMvcConfigurer {
@Bean(name = "customAsyncTaskExecutor")
public AsyncTaskExecutor customAsyncTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
int corePoolSize = Runtime.getRuntime().availableProcessors();
int maxPoolSize = corePoolSize * 2;
int queueCapacity = 500;
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setThreadNamePrefix("AsyncExecutor-");
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(60);
executor.initialize();
return executor;
}
@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
configurer.setTaskExecutor(customAsyncTaskExecutor());
configurer.setDefaultTimeout(5000);
}
}2. Write the SSE endpoint that streams online user count every 5 seconds:
@PreventDuplicateSubmit
@PreAuthorize("@permission.checker('monitor:online-user:list')")
@GetMapping(value = "/user-activity-sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux
streamUserActivitySSE() {
return Flux.interval(Duration.ofSeconds(5))
.flatMap(seq -> Mono.fromCallable(onlineUserService::getUserActivityNum)
.onErrorReturn(0));
}The front‑end can subscribe to /user-activity-sse and receive a continuous stream of numbers representing online users.
3. Real‑world case: a C++ ID‑card scanner required polling; using SSE would have eliminated the need for a 10‑minute quick‑and‑dirty polling implementation.
Conclusion: WebSocket, SSE, and polling each have their own strengths; choose SSE for lightweight one‑way push scenarios such as notifications, monitoring, or simple real‑time data, while WebSocket remains suitable for full bi‑directional communication.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.