Pains

726 pains collected

Severity:

Symbol-based visibility causes variable shadowing and naming conflicts

5

Go's reliance on symbol case for visibility (uppercase=public, lowercase=private) creates unintended variable shadowing. Developers cannot use natural names like 'user' for a user variable because it shadows the user type, forcing awkward one-letter naming conventions.

languageGo

Expensive error wrapping and stack trace overhead

5

Error wrapping up the call stack and garbage collection of intermediate objects is nearly as expensive as try-catch, yet requires manual coding. Stack traces provide redundant information most of the time and lack a mechanism to toggle them.

performanceGo

No standard library for GUI development, poor third-party solutions

5

Go lacks a standard library for GUI development. Third-party solutions exist but lack proper integration and comprehensive documentation, hindering cross-platform graphical application development.

ecosystemGo

50% of developers neglect testing in Go projects

5

Half of Go developers fail to write adequate unit tests, despite Go's testing package being available. This widespread neglect of testing reduces code reliability and maintainability.

testingGo

Excessive Syntactic Rules and Formatting Constraints

5

Go enforces many strict formatting and syntax rules that developers find overly rigid, including constraints on brace placement, variable declarations, and operator usage. These rules limit expressiveness and feel unnecessarily restrictive.

dxGo

Unclear and Opaque Go Language Contribution and Leadership Process

5

Only 25% of survey respondents found the Go language contribution process easy to understand, and only 28% felt the project leadership responded well to questions. This creates barriers for developers wanting to contribute or influence the language direction.

ecosystemGo

Premature Redis optimization introduces unnecessary complexity and failure modes

5

Teams often aggressively tune Redis before understanding their actual workload, tweaking memory policies, persistence settings, clustering, and sharding prematurely. This adds complexity and failure modes without solving real problems.

dxRedis

Client-server architecture with stateless HTTP requires complex session synchronization

5

Building web applications with stateless HTTP protocol and client-side JavaScript requires complex synchronization between client state and server-side session stores for simple features like shopping carts, increasing development complexity.

architectureHTTPJavaScript

Service discovery mechanisms are impractical for real-world use

5

Service discovery tools like UDDI registries were designed as centralized service catalogs but proved too cumbersome for practical use. Teams resorted to hard-coded endpoints implemented per-project, pointing to services others were unaware of.

ecosystemMicroservicesUDDI

Storing JSON blobs as strings prevents atomic field updates

5

Storing large JSON blobs in string format increases serialization/deserialization costs, network traffic latency, and eviction overhead. It prevents atomic field-level updates and makes tuning and scaling harder.

dxRedis

Multiple potential root causes complicate troubleshooting and monitoring

5

When Redis performance degrades, multiple potential causes exist (system load, memory pressure, poorly structured requests). Effective troubleshooting requires correlating and analyzing diverse data points across the system.

monitoringRedis

Manual memory eviction policy configuration required

5

Redis does not automatically manage memory like relational databases. Developers must manually configure eviction policies to handle out-of-memory scenarios, adding operational complexity and risk of data loss.

configRedis

Lack of built-in monitoring and observability

5

Redis lacks proper native monitoring and alerting mechanisms. Without adequate monitoring tools and manual setup, it is difficult to identify performance issues or potential failures before they impact production applications.

monitoringRedis

Poor data modeling and key design decisions

5

Developers fail to properly model data for Redis's key-value paradigm, making poor decisions about data organization and access patterns that lead to inefficiencies and performance issues.

dxRedis

Suboptimal use of pipelining and batch operations

5

Developers frequently fail to use Redis pipelining or batch operations, causing unnecessary round trips to the server and significant performance overhead.

performanceRedis

Over-optimization assumptions in schema design

5

GraphQL forces developers to think about every possible query variation upfront and design schemas accordingly. Generated GraphQL APIs that auto-expose storage models violate information hiding, force business logic onto API consumers, and are hard to evolve due to tight coupling.

architectureGraphQL

Type system duplication and code-first vs schema-first friction

5

Depending on the backend language and code generation approach, developers must manage two or more type systems (backend native types, GraphQL schema, generated client types). Code-first and schema-first approaches each have tradeoffs and friction points.

configGraphQL

Lack of standardized error handling

5

GraphQL returns HTTP 200 for most responses even when errors occur, making it difficult for clients to programmatically determine error nature. Errors are embedded in the response body without standardized error codes, forcing developers to implement custom error-handling logic and parse fragile error message strings.

dxGraphQL

GraphQL breaking change management without tooling support

5

GraphQL discourages breaking changes but provides no built-in tools to manage them, forcing developers who control all their clients to find workarounds and add needless complexity.

compatibilityGraphQL

Server/client data shape mismatches

5

Data structures often differ between the database and GraphQL responses. For example, a database field like `authorId` might be transformed into a nested object in GraphQL responses, creating misalignment and complicating data mapping.

dataGraphQL

GraphQL steep learning curve and debugging complexity

5

GraphQL has a significant learning curve compared to REST APIs. Developers must learn schema definitions, resolvers, and query structures, and debugging is more complex. Studies show developers find GraphQL challenging and time-consuming to learn with limited knowledge-base resources.

docsGraphQL

Lack of generic const expressions feature

5

Generic const expressions is the leading unimplemented/nightly-only feature blocking Rust development. 18.35% of developers say it would unblock their use case and 41.53% say it would improve their code.

compatibilityRust

Limited observability tooling for GraphQL request tracing

5

Developers lack adequate GUI tools for visualizing how requests move through GraphQL resolvers. Understanding request routing and resolver execution flow is more difficult than with simpler protocols, creating a gap in observability.

monitoringGraphQLOpenTelemetry

File Upload Handling

5

File uploads in GraphQL are significantly more complex than in REST APIs, requiring special handling on the server side. This adds substantial development overhead.

dxGraphQL