SlideShare a Scribd company logo
Event Sourcing
- what could go wrong?
Andrzej Ludwikowski
About me
➔
➔ ludwikowski.info
➔ github.com/aludwiko
➔ @aludwikowski
SoftwareMill
SoftwareMill
SoftwareMill
SoftwareMill
JVM
BLOGGERS
SoftwareMill
● Hibernate Envers
● Alpakka Kafka
● Sttp
● Scala Clippy
● Quicklens
● MacWire
What is Event Sourcing?
DB
Order {
items=[itemA, itemB]
}
What is Event Sourcing?
DB
DB
Order {
items=[itemA, itemB]
}
ItemAdded(itemA)
ItemAdded(itemC)
ItemRemoved(itemC)
ItemAdded(itemB)
History
● 9000 BC, Mesopotamian Clay Tablets,
e.g. for market transactions
History
● 2005, Event Sourcing
“Enterprise applications that use Event Sourcing
are rarer, but I have seen a few applications (or
parts of applications) that use it.”
Why Event Sourcing?
● complete log of every state change
● debugging
● performance
● scalability
● microservices integration pattern
ES and CQRS
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
modelRead
modelRead
models
ES and CQRS level 1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
modelRead
modelRead
models
Transaction
ES and CQRS level 1
● Entry-level, synchronous & transactional event sourcing
● slick-eventsourcing
ES and CQRS level 1
+ easy to implement
+ easy to reason about
+ 0 eventual consistency
- performance
- scalability
ES and CQRS level 2
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
modelRead
modelRead
models
Projector
Transaction
ES and CQRS level 2
+/- performance
+/- scalability
- eventual consistency
- increased events DB load ?
- lags
ES and CQRS level 3
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
modelRead
modelRead
models
Projector
Transaction
event
bus
ES and CQRS level 3.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
modelRead
modelRead
models
Projector
event
bus
Transaction
ES and CQRS level 3.1.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
modelRead
modelRead
models
Projector
event
bus
Transaction
ES and CQRS level 3.1.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
modelRead
modelRead
models
Projector
event
bus
Transaction
At-least-once delivery
ES and CQRS level 3.1.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
modelRead
modelRead
models
Projector
event
bus
Transaction
ES and CQRS level 3.1.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
modelRead
modelRead
models
Projector
event
bus
Transaction
ES and CQRS level 3.1.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
modelRead
modelRead
models
Projector
event
bus
Transaction
ES and CQRS level 3.1.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
modelRead
modelRead
models
Projector
event
bus
Transaction
ES and CQRS level 3.1.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
modelRead
modelRead
models
Projector
event
bus
Transaction
ES and CQRS level 3.1.1
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
modelRead
modelRead
models
Projector
event
bus
Transaction
?
ES and CQRS level 3.2
Events
Client
Query Service
Data access
Commands
Queries
Read
modelRead
modelRead
models
Projector
event
bus
Command Service
Domain
Command Service
Domain
Command Service
Domain
Transaction
`
Sharded
Cluster
ES and CQRS level 3.x
+ performance
+ scalability
- eventual consistency
- complex implementation
ES and CQRS alternatives
● Change Capture Data (CDC) logging instead of event bus?
● event bus instead of DB?
Not covered but worth to check
● Command Sourcing
● Event Collaboration
ES implementation?
● custom
● library
● framework
ES from domain perspective
● commands, events, state
● 2 methods on state
○ process(command: Command): List[Event]
○ apply(event: Event): State
ES from application perspective
● snapshotting
● fail-over
● recover
● debugging
● sharding
● serialization & schema evolution
● concurrency access
● etc.
import javax.persistence.*;
import java.util.List;
@Entity
public class Issue {
@EmbeddedId
private IssueId id;
private String name;
private IssueStatus status;
@OneToMany(cascade = CascadeType.MERGE)
private List<IssueComment> comments;
...
public void changeStatusTo(IssueStatus newStatus) {
if (this.status == IssueStatus.DONE
&& newStatus == IssueStatus.NEW || this.status == IssueStatus.NEW
&& newStatus == IssueStatus.DONE) {
throw new RuntimeException(String.format("Cannot change issue status from %s to %s",
this.status, newStatus));
}
this.status = newStatus;
}
...
}
import org.axonframework.commandhandling.*
import org.axonframework.eventsourcing.*
@Aggregate(repository = "userAggregateRepository")
public class User {
@AggregateIdentifier
private UserId userId;
private String passwordHash;
@CommandHandler
public boolean handle(AuthenticateUserCommand cmd) {
boolean success = this.passwordHash.equals(hashOf(cmd.getPassword()));
if (success) {
apply(new UserAuthenticatedEvent(userId));
}
return success;
}
@EventSourcingHandler
public void on(UserCreatedEvent event) {
this.userId = event.getUserId();
this.passwordHash = event.getPassword();
}
private String hashOf(char[] password) {
return DigestUtils.sha1(String.valueOf(password));
}
}
import akka.Done
import com.lightbend.lagom.scaladsl.*
import play.api.libs.json.{Format, Json}
import com.example.auction.utils.JsonFormats._
class UserEntity extends PersistentEntity {
override def initialState = None
override def behavior: Behavior = {
case Some(user) => Actions().onReadOnlyCommand[GetUser.type, Option[User]] {
case (GetUser, ctx, state) => ctx.reply(state)
}.onReadOnlyCommand[CreateUser, Done] {
case (CreateUser(name), ctx, state) => ctx.invalidCommand("User already exists")
}
case None => Actions().onReadOnlyCommand[GetUser.type, Option[User]] {
case (GetUser, ctx, state) => ctx.reply(state)
}.onCommand[CreateUser, Done] {
case (CreateUser(name), ctx, state) => ctx.thenPersist(UserCreated(name))(_ => ctx.reply(Done))
}.onEvent {
case (UserCreated(name), state) => Some(User(name))
}
}
}
ES packaging
● github.com/aludwiko/event-sourcing-akka-persistence
import java.time.Instant
import info.ludwikowski.es.user.domain.UserCommand.*
import info.ludwikowski.es.user.domain.UserEvent.*
import scala.util.{Failure, Success, Try}
final case class User (userId: UserId, name: String, email: Email) {
def applyEvent(userEvent: UserEvent): Try[User] = ??? //pattern matching
def process(userCommand: UserCommand): Try[List[UserEvent]] = ??? //pattern matching
}
object User {
def from(u: UserCreated): User = User(u.userId, u.name, u.email)
}
ES packaging
● snapshotting
● fail-over
● recover
● debugging
● sharding
● serialization & schema evolution
● concurrency access
● etc.
ES packaging
● domain logic
● domain validation
● 0 ES framework imports
library vs. framework
● Akka Persistence vs. Lagom
● Akka Persistence Typed?
Event storage
● file
● RDBMS
● Event Store
● MongoDB
● Kafka
● Cassandra
Event storage for Akka Persistence
● file
● RDBMS
● Event Store
● MongoDB
● Kafka
● Cassandra
akka-persistence-jdbc trap
val theTag = s"%$tag%"
sql"""
SELECT "#$ordering", "#$deleted", "#$persistenceId", "#$sequenceNumber",
"#$message", "#$tags"
FROM (
SELECT * FROM #$theTableName
WHERE "#$tags" LIKE $theTag
AND "#$ordering" > $theOffset
AND "#$ordering" <= $maxOffset
ORDER BY "#$ordering"
)
WHERE rownum <= $max"""
akka-persistence-jdbc trap
SELECT * FROM events_journal
WHERE tags LIKE ‘%some_tag%’;
Cassandra perfect for ES?
● partitioning by design
● replication by design
● leaderless (no single point of failure)
● optimised for writes (2 nodes = 100 000 tx/s)
● near-linear horizontal scaling
ScyllaDB ?
● Cassandra without JVM
○ same protocol, SSTable compatibility
● C++ and Seastar lib
● up to 1,000,000 IOPS/node
● not fully supported by Akka Persistence
Event serialization
● plain text
○ JSON
○ XML
○ YAML
● binary
○ java serialization
○ Avro
○ Protocol Buffers (Protobuf)
○ Thrift
○ Kryo
Plain text Binary
human-readable deserialization required
Plain text Binary
human-readable deserialization required
precision issues (JSON IEEE 754, DoS) -
Plain text Binary
human-readable deserialization required
precision issues (JSON IEEE 754, DoS) -
storage consumption compress
Plain text Binary
human-readable deserialization required
precision issues (JSON IEEE 754, DoS) -
storage consumption compress
slow fast
Plain text Binary
human-readable deserialization required
precision issues (JSON IEEE 754, DoS) -
storage consumption compress
slow fast
poor schema evolution support full schema evolution support
Binary
● java serialization
● Avro
● Protocol Buffers (Protobuf)
● Thrift
● Kryo
Binary
● java serialization
● Avro
● Protocol Buffers (Protobuf)
● Thrift
● Kryo
Binary
● java serialization
● Avro
● Protocol Buffers (Protobuf)
● Thrift
● Kryo
Binary
● java serialization
● Avro
● Protocol Buffers (Protobuf)
● Thrift
● Kryo
Multi-language support
● Avro
○ C, C++, C#, Go, Haskell, Java, Perl, PHP, Python, Ruby, Scala
● Protocol Buffers (Protobuf)
○ even more than Avro
Speed
https://code.google.com/archive/p/thrift-protobuf-compare/wikis/Benchmarking.wiki
Size
https://code.google.com/archive/p/thrift-protobuf-compare/wikis/Benchmarking.wiki
Full compatibility
Application
Events
● backward - V2 can read V1
V1
V2
● forward - V2 can read V3
Full compatibility
Application
Events
V1, V2
V2
Application
Application
V2
V3
● forward - V2 can read V3
Full compatibility
Events
Read
modelRead
modelRead
models
Projector
V2V3
Schema evolution - full compatibility
Protocol Buffers Avro
Add field + (optional) + (default value)
Remove field + + (default value)
Rename field + + (aliases)
https://martin.kleppmann.com/2012/12/05/schema-evolution-in-avro-protocol-buffers-thrift.html
Protobuf schema management
//user-events.proto
message UserCreatedEvent {
string user_id = 1;
string operation_id = 2;
int64 created_at = 3;
string name = 4;
string email = 5;
}
package user.application
UserCreatedEvent(
userId: String,
operationId: String,
createdAt: Long,
name: String,
email: String
)
Protobuf schema management
package user.domain
UserCreated(
userId: UserId,
operationId: OperationId,
createdAt: Instant,
name: String,
email: Email
) extends UserEvent
package user.application
UserCreatedEvent(
userId: String,
operationId: String,
createdAt: Long,
name: String,
email: String
)
Protobuf schema management
● def toDomain(event: UserCreatedEvent): UserEvent.UserCreated
● def toSerializable(event: UserEvent.UserCreated): UserCreatedEvent
Protobuf schema management
+ clean domain
- a lot of boilerplate code
Avro schema management
package user.domain
UserCreated(
userId: UserId,
operationId: OperationId,
createdAt: Instant,
name: String,
email: Email
) extends UserEvent
{
"type" : "record",
"name" : "UserCreated",
"namespace" :
"info.ludwikowski.es.user.domain",
"fields" : [ {
"name" : "userId",
"type" : "string" }, {
"name" : "operationId",
"type" : "string" }, {
"name" : "createdAt",
"type" : "long" }, {
"name" : "name",
"type" : "string" }, {
"name" : "email",
"type" : "string"
} ]
}
Avro deserialization
Bytes Deserialization Object
Reader SchemaWriter Schema
Avro writer schema source
● add schema to the payload
● custom solution
○ schema in /resources
○ schema in external storage (must be fault-tolerant)
○ Darwin project
● Schema Registry
Avro schema management
package user.domain
UserCreated(
userId: UserId,
operationId: OperationId,
createdAt: Instant,
name: String,
email: Email
) extends UserEvent
{
"type" : "record",
"name" : "UserCreated",
"namespace" :
"info.ludwikowski.es.user.domain",
"fields" : [ {
"name" : "userId",
"type" : "string" }, {
"name" : "operationId",
"type" : "string" }, {
"name" : "createdAt",
"type" : "long" }, {
"name" : "name",
"type" : "string" }, {
"name" : "email",
"type" : "string"
} ]
}
Protocol Buffers vs. Avro
{
"type" : "record",
"name" : "UserCreated",
"namespace" :
"info.ludwikowski.es.user.domain",
"fields" : [ {
"name" : "userId",
"type" : "string" }, {
"name" : "operationId",
"type" : "string" }, {
"name" : "createdAt",
"type" : "long" }, {
"name" : "name",
"type" : "string" }, {
"name" : "email",
"type" : "string"
} ]
}
message UserCreatedEvent {
string user_id = 1;
string operation_id = 2;
int64 created_at = 3;
string name = 4;
string email = 5;
}
Avro schema management
+ less boilerplate code
+/- clean domain
- reader & writer schema distribution
Avro
+ less boilerplate code
+/- clean domain
- reader & writer schema distribution
Protobuf
+ clean domain
- a lot of boilerplate code
Avro vs. Protocol Buffers
● The best serialization strategy for Event Sourcing
Event Sourcing - what could possibly go wrong?
Event Sourcing - what could possibly go wrong?
Memory consumption
Event Sourcing - what could possibly go wrong?
Immutable vs. mutable state?
● add/remove ImmutableList 17.496 ops/s
● add/remove TreeMap 2201.731 ops/s
Event Sourcing - what could possibly go wrong?
Fixing state
● healing command
Updating all aggregates
User(id)Command(user_id) Event(user_id)Event(user_id)Event(user_id)
Handling duplicates
Events
Read
modelRead
modelRead
models
Projector
event
bus
At-least-once delivery
https://www.seriouspuzzles.com/unicorns-in-fairy-land-500pc-jigsaw-puzzle-by-eurographics/
Handling duplicates
Events
Read
modelRead
modelRead
models
Projector
event
bus
At-least-once delivery
Handling duplicates
Events
Read
modelRead
modelRead
models
Projector
event
bus
idempotent updates
Event + seq_noEvent + seq_no
Handling duplicates
Events
Read
modelRead
modelRead
models
Projector
event
bus
Event + seq_no
read model update +
seq_no
Broken read model
Events
ad model
ead model
Read
models
Projector
event
bus
Broken read model
Events
ad model
ead model
Read
models
Projector
event
bus
read model update + offset
(manual offset management)
Multi aggregate transactional update
● rethink aggregates boundaries
● compensating action
○ optimistic
○ pessimistic
Pessimistic compensation action
User account
Cinema hall
Pessimistic compensation action
User account
Cinema hall
charged
Pessimistic compensation action
User account
Cinema hall
charged
booked
Pessimistic compensation action
User account
Cinema hall
charged
booked sold out
Pessimistic compensation action
User account
Cinema hall
charged
booked
booked sold out
Pessimistic compensation action
User account
Cinema hall
charged
booked
booked sold out
Pessimistic compensation action
User account
Cinema hall
charged
booked
booked sold out
refund
Optimistic compensation action
User account
Cinema hall
charged
booked sold out
Optimistic compensation action
User account
Cinema hall booked
booked sold out
overbooked
Optimistic compensation action
User account
Cinema hall
charged
booked
booked sold out
overbooked
?
Saga
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
modelRead
modelRead
models
Updater
event
bus
Transaction
Saga
Command Service
Domain
Events
Query Service
Data access
Commands Queries
Read
modelRead
modelRead
models
Projector
event
bus
Transaction
Saga
Command Service
Domain
Events
Client
Query Service
Data access
Commands Queries
Read
modelRead
modelRead
models
Projector
event
bus
Transaction
Saga
● should be persistable
● events order should be irrelevant
● time window limitation
● compensating action must be commutative
Saga
● Sagas with ES
● DDD, Saga & Event-sourcing
● Applying Saga Pattern
● Microservice Patterns
ES with RODO/GDPR
● “right to forget” with:
○ data shredding (and/or deleting)
■ events, state, views, read models
○ retention policy
■ message brokers, backups, logs
○ data before RODO migration
ES and CQRS level 3.2
Events
Client
Query Service
Data access
Commands
Queries
Read
modelRead
modelRead
models
Projector
event
bus
Command Service
Domain
Command Service
Domain
Command Service
Domain
Transaction
Sharding
Clustering
Cluster = split brain
1
5 4
3
Load balancer
2
Cluster = split brain
1
5 4
3
Load balancer
2
User(1)
Command(1)
Cluster = split brain
1
5 4
3
Load balancer
2
Cluster = split brain
1
5 4
3
Load balancer
2
User(1)
Cluster = split brain
1
5 4
3
Load balancer
2
User(1)
Command(1)
User(1)
Cluster = split brain
1
5 4
3
Load balancer
2
User(1)
Command(1)
User(1)
Command(1)
Cluster best practises
● remember about the split brain
● very good monitoring & alerting
● a lot of failover tests
● cluster also on dev/staging
● keep it as small as possible (code base, number of nodes, etc.)
Summary
● carefully choose ES lib/framework
● understand event/command/state schema evolution
● eventual consistency is your friend
● scaling is complex
● database inside-out
● log-based processing mindset
Event Sourcing - what could possibly go wrong?
Rate me please :)
Thank you and Q&A
➔
➔ ludwikowski.info
➔ github.com/aludwiko
➔ @aludwikowski
WE
WANT
YOU
Want to learn more?
● Akka Typed Fundamentals (Java/Scala)
● Reactive Event Sourcing with Akka (Java/Scala)
● Performance tests with Gatling

More Related Content

PDF
Andrzej Ludwikowski - Event Sourcing - what could possibly go wrong? - Codemo...
PDF
Event sourcing - what could possibly go wrong ? Devoxx PL 2021
PPTX
Kick your database_to_the_curb_reston_08_27_19
PDF
Robust Operations of Kafka Streams
PDF
Webinar: Deep Dive on Apache Flink State - Seth Wiesman
PDF
Introduction to the Processor API
PDF
Distributed Real-Time Stream Processing: Why and How 2.0
PDF
Building Scalable and Extendable Data Pipeline for Call of Duty Games: Lesson...
Andrzej Ludwikowski - Event Sourcing - what could possibly go wrong? - Codemo...
Event sourcing - what could possibly go wrong ? Devoxx PL 2021
Kick your database_to_the_curb_reston_08_27_19
Robust Operations of Kafka Streams
Webinar: Deep Dive on Apache Flink State - Seth Wiesman
Introduction to the Processor API
Distributed Real-Time Stream Processing: Why and How 2.0
Building Scalable and Extendable Data Pipeline for Call of Duty Games: Lesson...

What's hot (20)

PDF
Riddles of Streaming - Code Puzzlers for Fun & Profit (Nick Dearden, Confluen...
PDF
Kafka Streams: the easiest way to start with stream processing
PDF
Apache kafka meet_up_zurich_at_swissre_from_zero_to_hero_with_kafka_connect_2...
PDF
Exactly-Once Made Easy: Transactional Messaging Improvement for Usability and...
PPTX
Stream processing - Apache flink
PDF
Real World Serverless
PDF
Kafka Summit NYC 2017 - The Best Thing Since Partitioned Bread
PDF
Apache Kafka: New Features That You Might Not Know About
PDF
Cracking JWT tokens: a tale of magic, Node.js and parallel computing - Code E...
PDF
Data in Motion: Streaming Static Data Efficiently
PDF
A dive into akka streams: from the basics to a real-world scenario
PPTX
Fabric - Realtime stream processing framework
PPTX
Dropwizard Internals
PDF
Building Scalable Stateless Applications with RxJava
PDF
HBase RowKey design for Akka Persistence
PDF
Benchx: An XQuery benchmarking web application
PPTX
Stream Application Development with Apache Kafka
PDF
Spark streaming: Best Practices
PDF
Resilient Applications with Akka Persistence - Scaladays 2014
PPTX
KSQL and Kafka Streams – When to Use Which, and When to Use Both
Riddles of Streaming - Code Puzzlers for Fun & Profit (Nick Dearden, Confluen...
Kafka Streams: the easiest way to start with stream processing
Apache kafka meet_up_zurich_at_swissre_from_zero_to_hero_with_kafka_connect_2...
Exactly-Once Made Easy: Transactional Messaging Improvement for Usability and...
Stream processing - Apache flink
Real World Serverless
Kafka Summit NYC 2017 - The Best Thing Since Partitioned Bread
Apache Kafka: New Features That You Might Not Know About
Cracking JWT tokens: a tale of magic, Node.js and parallel computing - Code E...
Data in Motion: Streaming Static Data Efficiently
A dive into akka streams: from the basics to a real-world scenario
Fabric - Realtime stream processing framework
Dropwizard Internals
Building Scalable Stateless Applications with RxJava
HBase RowKey design for Akka Persistence
Benchx: An XQuery benchmarking web application
Stream Application Development with Apache Kafka
Spark streaming: Best Practices
Resilient Applications with Akka Persistence - Scaladays 2014
KSQL and Kafka Streams – When to Use Which, and When to Use Both
Ad

Similar to Event Sourcing - what could possibly go wrong? (20)

PDF
Andrzej Ludwikowski - Event Sourcing - co może pójść nie tak?
PDF
Event Sourcing - what could go wrong - Devoxx BE
PDF
Event Sourcing - what could go wrong - Jfokus 2022
PDF
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
PDF
Building a serverless company on AWS lambda and Serverless framework
PDF
NetflixOSS Open House Lightning talks
PPTX
Cqrs and event sourcing in azure
PDF
Lightbend Lagom: Microservices Just Right
PPTX
Intellias CQRS Framework
PDF
CHOReOS Web Services FISL Conference Brazil 2012
PDF
Decompose the monolith into AWS Step Functions
PPTX
Docker & ECS: Secure Nearline Execution
PDF
Tweaking performance on high-load projects
PDF
iguazio - nuclio overview to CNCF (Sep 25th 2017)
PDF
nuclio Overview October 2017
PPTX
Automating the Entire PostgreSQL Lifecycle
PDF
Kerberizing spark. Spark Summit east
PDF
Logging for Production Systems in The Container Era
PDF
Como creamos QuestDB Cloud, un SaaS basado en Kubernetes alrededor de QuestDB...
PPTX
Andrii Dembitskyi "Events in our applications Event bus and distributed systems"
Andrzej Ludwikowski - Event Sourcing - co może pójść nie tak?
Event Sourcing - what could go wrong - Devoxx BE
Event Sourcing - what could go wrong - Jfokus 2022
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Building a serverless company on AWS lambda and Serverless framework
NetflixOSS Open House Lightning talks
Cqrs and event sourcing in azure
Lightbend Lagom: Microservices Just Right
Intellias CQRS Framework
CHOReOS Web Services FISL Conference Brazil 2012
Decompose the monolith into AWS Step Functions
Docker & ECS: Secure Nearline Execution
Tweaking performance on high-load projects
iguazio - nuclio overview to CNCF (Sep 25th 2017)
nuclio Overview October 2017
Automating the Entire PostgreSQL Lifecycle
Kerberizing spark. Spark Summit east
Logging for Production Systems in The Container Era
Como creamos QuestDB Cloud, un SaaS basado en Kubernetes alrededor de QuestDB...
Andrii Dembitskyi "Events in our applications Event bus and distributed systems"
Ad

More from Andrzej Ludwikowski (8)

PDF
Event-driven systems without pulling your hair out
PDF
Performance tests - it's a trap
PDF
Cassandra lesson learned - extended
PDF
Performance tests with Gatling (extended)
PPTX
Stress test your backend with Gatling
PPTX
Performance tests with Gatling
PDF
Cassandra - lesson learned
PPTX
Annotation processing tool
Event-driven systems without pulling your hair out
Performance tests - it's a trap
Cassandra lesson learned - extended
Performance tests with Gatling (extended)
Stress test your backend with Gatling
Performance tests with Gatling
Cassandra - lesson learned
Annotation processing tool

Recently uploaded (20)

PDF
Navsoft: AI-Powered Business Solutions & Custom Software Development
PPTX
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
PDF
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
PPTX
ISO 45001 Occupational Health and Safety Management System
PDF
medical staffing services at VALiNTRY
PPTX
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PDF
Nekopoi APK 2025 free lastest update
PPTX
L1 - Introduction to python Backend.pptx
PDF
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PPT
Introduction Database Management System for Course Database
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PDF
System and Network Administration Chapter 2
PDF
How to Choose the Right IT Partner for Your Business in Malaysia
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PPTX
CHAPTER 2 - PM Management and IT Context
PDF
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
PDF
Digital Strategies for Manufacturing Companies
Navsoft: AI-Powered Business Solutions & Custom Software Development
Lecture 3: Operating Systems Introduction to Computer Hardware Systems
Claude Code: Everyone is a 10x Developer - A Comprehensive AI-Powered CLI Tool
ISO 45001 Occupational Health and Safety Management System
medical staffing services at VALiNTRY
CHAPTER 12 - CYBER SECURITY AND FUTURE SKILLS (1) (1).pptx
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
Nekopoi APK 2025 free lastest update
L1 - Introduction to python Backend.pptx
Internet Downloader Manager (IDM) Crack 6.42 Build 42 Updates Latest 2025
Wondershare Filmora 15 Crack With Activation Key [2025
Introduction Database Management System for Course Database
Which alternative to Crystal Reports is best for small or large businesses.pdf
System and Network Administration Chapter 2
How to Choose the Right IT Partner for Your Business in Malaysia
Softaken Excel to vCard Converter Software.pdf
Odoo Companies in India – Driving Business Transformation.pdf
CHAPTER 2 - PM Management and IT Context
Raksha Bandhan Grocery Pricing Trends in India 2025.pdf
Digital Strategies for Manufacturing Companies

Event Sourcing - what could possibly go wrong?