21
Optimizing your Web application From 4 RPS to 200+ RPS in 90 minutes Nuno Caneco @FullstackLX - 2017/04/06

Fullstack LX - Improving your application performance

Embed Size (px)

Citation preview

Page 1: Fullstack LX - Improving your application performance

Optimizing your Web application

From 4 RPS to 200+ RPS in 90 minutes

Nuno Caneco @FullstackLX - 2017/04/06

Page 2: Fullstack LX - Improving your application performance

Who am I

Nuno Caneco

Senior Software Engineer @ Talkdesk

/nunocaneco

[email protected]

Page 3: Fullstack LX - Improving your application performance

File > New > Project

Page 4: Fullstack LX - Improving your application performance

Project facts● Team: 5 devs + 1 team lead + 1 tester● Duration: 18x 2-week sprints

● 165 KLOC: 27 KLOC of which are automated tests

KLOC = 1.000 lines of code

Central

Local

WindowsPOS

Windows Mobile

terminal

Page 5: Fullstack LX - Improving your application performance

The due date is coming...

depl

oy

Page 6: Fullstack LX - Improving your application performance

So, we questioned ourselves

Will it handle data in PROD?

Will it be fast enough?

Will the database perform?

Will the users complain?

Page 7: Fullstack LX - Improving your application performance
Page 8: Fullstack LX - Improving your application performance

The purpose of this session

Share

the

preparatio

n

work

Page 9: Fullstack LX - Improving your application performance

TALK IS CHEAP

SHOW ME THE CODE

Page 10: Fullstack LX - Improving your application performance

Tip #1: Check the databaseINDEXES: ● Choose the indexes wisely● Use multi-column indexes● Pay attention to the order of the columns● Use Filtered Indexes● Use Included Columns

Stored Procedures / Functions: use them for the most data intensive features● And spend some time optimizing those!

Page 11: Fullstack LX - Improving your application performance

Tip #2: Fine tune the PROD databaseDefaults are not always PROD ready

FILEGROUPS:● Separate tables and indexes into different FILEGROUPS● Isolate large tables on different FILEGROUPS

Hard drives:● Allocate fastest hard drives to indexes and mission critical tables● Make sure the tempdb is on the fastest storage possible

Page 12: Fullstack LX - Improving your application performance

Tip #3: Know your ORMProfile the queries generated by the ORM:

● Find optimizations for the ORM-generated queries

● Make sure the queries are hitting INDEXES

Page 13: Fullstack LX - Improving your application performance

Tip #4: Optimize data transfers● Use Stored Procedures for critical or high-load reads

● Use dedicated Types for Slim classes○ Results for Search or List operations

● Take care of the ORM query clauses

Page 14: Fullstack LX - Improving your application performance

Tip #5: Lazy vs Eager loadingusing (var context = new DbContext()){

// SELECT * from Messages WHERE ID = @messageIdvar message = context.Messages.SingleOrDefault(m => m.ID == messageId);// SELECT * FROM User WHERE ID = @message.ToUserFKvar toUser = message.ToUser;

// Now imagine this on a loop...}

versus

using (var context = new DbContext()){

// SELECT * FROM Messages INNER JOIN Users ON (...)var message = context.Messages .Include("ToUser")

.SingleOrDefault(m => m.ID == messageId);}

Page 15: Fullstack LX - Improving your application performance

Tip #6: Use Prepared StatementsUse Prepared Statements

● When performing queries to the database via ADO.NET/JDBC/ODBC○ It allows the database to cache and reuse Execution Plans among requests

● Avoid setting parameters on Strings via concatenation

var command = String.Format("SELECT * FROM Message WHERE FromUserFK = {0}", fromUserId);

versus

var command = new SqlCommand("SELECT * FROM Message WHERE FromUserFK = @fromUserFk", connection);command.Parameters.AddWithValue("@fromUserFK", fromUserId);

Page 16: Fullstack LX - Improving your application performance

Tip #7: Cache stuffStore data in Cache

○ Reference tables○ Read-mostly data○ Recently read data

● Choose the most appropriate caching platform:○ Local Cache: MemCache (C#),○ Distributed Cache: Redis, memcached

But…● Measure the cost of querying the cache:

○ A round-trip to the network can take a few milliseconds

Page 17: Fullstack LX - Improving your application performance

Tip #8: RAM is cheap, but...Avoid unnecessary data loads

○ Especially large data blocks

Stateless objects should be singletons

Optimize your code○ Avoid the ‘+’ to concatenate strings; Use StringBuilder() or String.Format() variants instead○ Optimize loops○ Avoid expensive operations○ Beware of data serialization○ Network consumes time

Page 18: Fullstack LX - Improving your application performance

Tip #9: Mind the loggerLogging to Database causes LOCKs

and potential Exceptions on the application

Sync logging to disk causes contention → use async logging if you can

Use "Format" overloads to avoid unnecessary string concatenation

string[] operationResult = DoSomething();logger.DebugFormat("The result of this long running is {0}", string.Join(operationResult,";"));

// A better approachif(logger.IsDebugEnabled){ logger.DebugFormat(" The result of this long running is {0}", string.Join(operationResult,";"));}

Page 19: Fullstack LX - Improving your application performance

Engineering is about balanceScalability

PerformanceFeatures & User Experience

Dev effort and timeOverall complexity

Maintainability

Cost vs Benefit

Page 20: Fullstack LX - Improving your application performance

Q&A

Questions ?