Charles Proxy: The Web Debugging Tool You Never Knew You Needed


Being a developer can sometimes feel like being a handyman. Besides building applications, websites and other well-working digital products, we also need to inspect, maintain or upgrade these products if necessary.

And just like handymen, we also have a few favorite tools to help us tighten those pesky digital loose screws. When it comes to web debugging, for example, our tool-of-choice is a reliable friend of ours: Charles Proxy.

Read on to find out more about:

  • What Charles Proxy does as a web debugging tool
  • The top five reasons why we use Charles Proxy in our workflow
  • Our favorite Charles Proxy features: Throttle, Breakpoint, Rewrite and Map Local
  • The limitations and (many) benefits of using Charles Proxy

Who is this “Charles”, anyway?

Put simply, Charles Proxy is a tool that inspects and analyzes the traffic between your device and the internet. It helps us (and by “us”, we mean developers and QA engineers) understand how data is sent and received within our application’s environment – making it easier to find (and fix) communication issues between our app and the web.

Looking at it on a more granular level, we can say that Charles Proxy intercepts requests, shows their details and even modifies them – something that’s incredibly helpful when we’re debugging and improving network-related problems!

And if this wasn’t enough, here are five more reasons why we prefer adding Charles Proxy to our workflow:

  1. Because black box testing is like shooting in the dark
    When we step into a room blindfolded, we can’t see anything: no furniture, no surroundings… It’s the same with black box testing! But with Charles Proxy, the blindfold suddenly comes off, and we can see the details inside the room: how our application talks to the internet, what data it’s sending, how it’s working, and a million other small factors.
  2. Because we can manipulate our app’s behavior in better ways
    By letting us create different test scenarios (like slowing down connections, pausing interactions, or rewriting the data within the app environment), Charles Proxy helps us uncover potential issues that we wouldn’t find if the application was running smoothly, so we can prepare it for these situations in the future.
  3. Because Charles Proxy allows cross-platform data validation
    What’s a critical aspect of app development and testing that also guarantees consistent and accurate information exchange between different devices, operating systems, and/or platforms? Cross-platform data validation, of course: since Charles Proxy acts like a friendly interpreter who makes sure everyone hears the same message, it helps us build a smooth user experience for all devices and platforms!
  4. Because we gain better visibility of issues and their causes
    Just like a spotlight lights up dark spaces, Charles Proxy shows us what’s going on behind the scenes. More specifically, what the conversation between our app and the server is actually like. This way, we can quickly identify the root cause of an issue and see whether it’s happening in the user interface (FE) or in the app’s logic and data (BE).
  5. Because Charles Proxy lets us perform basic security testing
    Last but not least, Charles Proxy helps us detect if sensitive information (like passwords, credit card numbers, or personal data) is being sent over the internet in plain text while using our app. We can also examine how the app handles user authentication and authorization, as well as manipulating the input data and testing how the app handles it. In other words, it can be a one-stop-shop for testing all our basic security needs.

It follows from all this that Charles Proxy makes it significantly easier for us to optimize performance, ensure reliable connections, and enhance the overall user experience of each app we build. Isn’t it amazing what a comprehensive view of our application functionalities will let us do?

Getting to know Charles proxy

Now we’ve established why we believe in using Charles Proxy to help optimize our digital products, we want to introduce you properly to this particular web debugging friend of ours. But instead of taking you all the way through the installation process, we thought we’d jump right into the meatier part of things and showcase our four favorite functionalities – a.k.a. the ones that we use the most during our workflows and development processes: Throttling, Breakpoint, Rewrite and Map Local

A. The One That Challenges Us: Throttling
Remember what we said about Charles Proxy letting us manipulate our app’s behavior? This is the functionality that does just that: Throttling basically allows us to simulate different network conditions (like slow or unreliable connections) to test how our application performs under less-than-ideal circumstances.
By adjusting the speed and reliability of the network connection, Throttling lets us see how our app behaves during slow loading times, high latency or interrupted data transfers… Which then helps us identify performance bottlenecks, optimize data usage and finetune our app to work seamlessly for our users – regardless of their network quality!

Quick tip?

If you want to simulate a weaker, 2G cellular network, use this configuration:

  • Bandwidth: 256 kbps (both upload and download)
  • Utilization: 100%
  • Latency: 300 ms
  • MTU: 1500 bytes
  • Reliability: 75%
  • Stability: 75%
  • Unstable quality range: 20% to 25%

B. The One That Makes Us Pause: Breakpoint

First things first: what is a breakpoint (in programming, that is)? According to Techopedia, a breakpoint is “an intentional stop marked in the code of an application where execution pauses for debugging.” When it comes to the Breakpoint functionality in Charles Proxy, it effectively stops requests going out or responses going in – so we can inspect them and edit them.

The great thing about this is that it lets us test different scenarios that would otherwise be very difficult (or annoying!) to trigger manually in the app’s UI. Adding a breakpoint in Charles Proxy is simple: just right-click on the host name you want to intercept, select Breakpoint in the interface, then go to Proxy and Breakpoint Settings and you’ll see your newly added breakpoint there!

Here are some test ideas to try out when editing requests in Breakpoint:

  • Remove mandatory fields and see how the backend copes (you can do this by either removing the field altogether, or submitting an empty field).
  • Exceed the maximum number of characters allowed in a field, e.g. if you can only enter 15 characters in the UI, edit the request and enter 20 characters instead.
  • Enter invalid data in one of the fields, e.g. only enter numbers into a name field.

C. The One That Fakes Mistakes: Rewrite
Fair warning: this is not for the faint of heart. But the good news is that once it’s set up, we can use and amend the Rewrite feature in Charles Proxy to return different HTTP Server Response Codes (like simulating a 500 Internal Server Error, for example). Not a bad trick for developers to have in their toolbox!

Here’s how you do it:

  • Go to the Tools menu in Charles Proxy and select Rewrite. This will open the Rewrite tool interface.
  • Click on the Add button (+) to create a new rule.
  • In the rule configuration window, you can specify conditions to match requests. You can, for example, set the URL or domain where you want to trigger the error – let’s say you want to trigger the error for requests to https://example.com/api.
  • Under the Action section of Rewrite, select Edit Response.
  • In the Edit Response window, change the Response Code field to e.g. “500 Internal Server Error”.
  • After configuring the Rewrite rule to trigger the 500 error, click on OK or Apply to save the rule.
  • Now, if your application makes a request to https://example.com/api (or any URL that matches your configured condition), Charles Proxy will intercept the response and modify it to have a 500 Internal Server Error status.
  • You can check the response details in Charles Proxy to verify that the error has been triggered, and observe how your application handles this type of error response. (Remember to revert/remove your configured Rewrite rule after you’ve tested it, so your app doesn’t begin behaving strangely!)

D. The One That Mixes it Up: Map Local
And finally, Charles Proxy’s Map Local feature lets us replace server responses with locally stored files. This gives us flexibility in testing scenarios, letting us replicate a variety of conditions without relying on real network responses – scenarios like:

  • Offline Testing: simulate offline mode by mapping API responses to local files, ensuring your app’s behavior without an active internet connection.
  • Performance Testing: test your app’s speed and responsiveness by mapping responses to locally stored files with different sizes to simulate various network conditions.
  • Error Scenarios: mimic server errors (e.g. 404 or 500) by mapping responses to local error pages, making sure your app handles errors gracefully.
  • Localization Testing: map responses to localized content files to verify that your app displays correct translations.
  • Third-Party Services: map responses from third-party APIs to local data, letting you test your app without relying on external services.
  • Load Testing: Simulate heavy server load by mapping responses to cached files, observing how your app performs under stress.

So Charles Proxy Can Do Everything?!

Not quite everything. Like every useful tool (digital or physical), Charles Proxy has its own limitations. Apps that use SSL pinning – a security technique that prevents intercepting encrypted connections – can make it challenging for Charles Proxy to decode the encrypted data, for example; and in order to analyze SSL traffic from Android 7+ applications, we need to configure a Network Security Configuration file for our app. (This configuration enables SSL handshake interception by Charles Proxy, allowing us to view and analyze the encrypted data.)

There’s also a bit of a learning curve when it comes to understanding Charles Proxy’s functionalities – especially for users new to network debugging and analysis tools. (Which is, incidentally, one of the reasons for us putting together this overview!) And since Charles Proxy only has a 30-day active free trial before switching to a licenced (i.e. purchased) model, taking full advantage of the many advanced features it has to offer may require some intense onboarding at the very beginning.

However, the many benefits of using Charles Proxy in our daily work – for us here at Mooncascade, at least! – far outshine these constraints.

Here are just a few of our favorite benefits (or perks, if you will):

Quick and Easy SetupIt’s pretty straightforward to install Charles Proxy. We can quickly set up the tool and start capturing network traffic for analysis. (Which means we can start with network debugging tasks that much faster!)
Affordable One-Time PurchaseAlthough, as we said, Charles Proxy comes with a license (after a free 30-day trial), it has a one-time purchase model, and it’s pretty affordable. This cost-effective approach lets us access the tool’s features without any monthly subscription fees, making it quite a budget-friendly choice for our network analysis needs.
Single VPN Slot RequirementUnlike other network analysis tools that usually require multiple VPN slots for interception, Charles Proxy only needs one. This way, it doesn’t need to compete for limited VPN resources and guarantees a dedicated connection for all our debugging needs.
User-Friendly Learning CurveJust because Charles Proxy has a bit of a learning curve doesn’t mean it’s unenjoyable: in fact, it’s pretty user-friendly, with an intuitive interface and well-organized features helping users to grasp its functionalities more easily. Even while learning on the go!
Enhanced Application InsightsCharles Proxy helps us get a deeper understanding of our applic’s inner workings by capturing and visualizing network traffic. These insights show us how our app communicates with servers, identifies potential bottlenecks, and ensures optimal performance… All which help us optimize performance.
Various Test ScenariosWe can’t overstate how useful it is to create and manipulate diverse test scenarios in Charles Proxy. By simulating different network conditions, response times or error responses, it’s so much easier to comprehensively test our app’s behavior under different (and more challenging) circumstances.
Detailed Bug TicketsWhen Charles Proxy finds issues in your application, it lets us create more detailed bug tickets: the precise network data it captures provides us with more comprehensive information, and helps us fix these bugs much faster.

Closing considerations: Charles Proxy, A Friend Worth Having
After all is said and done, we can safely say that we believe in the many positive attributes of Charles Proxy: it definitely helps us make all applications and digital products we create even more reliable and robust.

And we can show you exactly what we mean: get in touch today and we’ll give you a special walk-through of just what we’ve created with Charles Proxy’s help over these last few months.


Have a project on horizon? Let's talk