Pains
726 pains collected
Symbol-based visibility causes variable shadowing and naming conflicts
5Go'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.
Expensive error wrapping and stack trace overhead
5Error 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.
No standard library for GUI development, poor third-party solutions
5Go lacks a standard library for GUI development. Third-party solutions exist but lack proper integration and comprehensive documentation, hindering cross-platform graphical application development.
50% of developers neglect testing in Go projects
5Half 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.
Excessive Syntactic Rules and Formatting Constraints
5Go 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.
Unclear and Opaque Go Language Contribution and Leadership Process
5Only 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.
Premature Redis optimization introduces unnecessary complexity and failure modes
5Teams 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.
Client-server architecture with stateless HTTP requires complex session synchronization
5Building 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.
Service discovery mechanisms are impractical for real-world use
5Service 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.
Storing JSON blobs as strings prevents atomic field updates
5Storing 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.
Multiple potential root causes complicate troubleshooting and monitoring
5When 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.
Manual memory eviction policy configuration required
5Redis 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.
Lack of built-in monitoring and observability
5Redis 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.
Poor data modeling and key design decisions
5Developers 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.
Suboptimal use of pipelining and batch operations
5Developers frequently fail to use Redis pipelining or batch operations, causing unnecessary round trips to the server and significant performance overhead.
Over-optimization assumptions in schema design
5GraphQL 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.
Type system duplication and code-first vs schema-first friction
5Depending 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.
Lack of standardized error handling
5GraphQL 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.
GraphQL breaking change management without tooling support
5GraphQL 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.
Server/client data shape mismatches
5Data 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.
GraphQL steep learning curve and debugging complexity
5GraphQL 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.
Lack of generic const expressions feature
5Generic 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.
Limited observability tooling for GraphQL request tracing
5Developers 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.
File Upload Handling
5File uploads in GraphQL are significantly more complex than in REST APIs, requiring special handling on the server side. This adds substantial development overhead.